First element binding disconnect bug
After an element removal from observable array, binding to first element becomes one way, i.e. model -> view
by Silvestrs Kante
HTML
<script src="https://rawgit.com/mbest/knockout-repeat/master/knockout-repeat.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.11/require.js"></script>
<div class="row">Total amount: <span data-bind="text: TotalAmount()"></span>
</div>
<div class="row"> <span data-bind="repeat: {foreach: Columns, item: '$col'}" data-repeat-bind="text: $col().DisplayName"></span>
</div>
<div class="row" data-bind="repeat: {foreach: LineItemList, item: '$row'}">
<div class="inner-row" data-bind="repeat: {foreach: Columns, item: '$col'}">
<!-- ko if: $index===0 --> <span>Amount</span>
<!-- /ko -->
<!-- ko if: $index===1 -->
<input type="text" data-bind="numericValue: $row()[$col().DBName], valueUpdate: 'afterkeydown'" />
<!-- /ko -->
</div>
</div>
<div class="row">
<button data-bind="click: RemoveLastItem">Remove e.g. last item</button>
</div>
JavaScript
ko.bindingHandlers.numericValue = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.dependentObservable({
read: underlyingObservable,
write: function (value) {
if (!isNaN(value) && value.length > 0) {
underlyingObservable(parseFloat(value));
} else {
underlyingObservable(value);
}
}
});
ko.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor);
},
update: ko.bindingHandlers.value.update
};
var root = this;
define('jquery', [], function () {
return root.jQuery;
});
define('ko', [], function () {
return root.ko;
});
define('lodash', [], function () {
return root._;
});
define('vm', ['jquery', 'ko', 'lodash'], function ($, ko, _) {
var data = {
LineItemsData: [{
ID: 2,
Amount: 500
}, {
ID: 3,
Amount: 234.56
}, {
ID: 4,
Amount: 0.00
}]
};
var LineItemMapping = {
'LineItemsData': {
create: function (options) {
console.log(options)
return new LineItem(
options.data.ID,
options.data.Amount);
}
}
};
var Invoice = {
LineItemsData: ko.observableArray([])
};
function LineItem(setID, setAmount) {
var self = this;
self.ID = setID;
self.Amount = ko.observable(setAmount);
return {
ID: self.ID,
Amount: self.Amount
};
}
function Column(setDBName, setDisplayName) {
this.DBName = setDBName;
this.DisplayName = setDisplayName;
}
var Columns = ko.observableArray([
new Column("ID", "ID"),
new Column("Amount", "Line Item Amount")]);
...