I have a view model, which has several collection properties with some repeating logic. I need to be able to add a new empty object, to remove an object, and to ensure that every collection has at least one object, and if it is the only object, "Delete" button should be disabled.
To extract these common functions I extended kendo.data.ObservableArray
:
function addEmpty() {
this.push({});
}
function hasMoreThanOne {
return this.length > 1;
}
var CoolObservableArray = kendo.data.ObservableArray.extend({
init: function(data) {
kendo.data.ObservableArray.fn.init.call(this, data);
this.addEmpty = addEmpty.bind(this);
this.hasMoreThanOne = hasMoreThanOne.bind(this);
}
});
The problem is with hasMoreThanOne
function. When I create an array with a single element, "Delete" button gets disabled - it is ok - but when I add new elements, it does not get enabled.
To refresh the UI kendo's get
function need to be called, but it needs a parameter referencing to the property name, which will vary for each instance of CoolObservableArray
, so I need to write repeating functions for each collection like deleteXXXEnabled
, deleteYYYEnabled
, etc.. How can I avoid it?
Here is the fiddle with problem reproduction: http://dojo.telerik.com/AFOMa/2
The source binding only renders the new object that you add to the ObservableArray
because the change event which notifies the binding only indicates that a new item was added.
You can force the source binding to re-render the whole view by triggering a change event manually:
var CoolObservableArray = kendo.data.ObservableArray.extend({
init: function (data, type) {
kendo.data.ObservableArray.prototype.init.call(this, data, type);
this.addEmpty = addEmpty.bind(this);
this.deleteObject = deleteObject.bind(this);
this.hasMoreThanOne = hasMoreThanOne.bind(this);
this.bind("change", function (e) {
if (e.action === "add" || e.action === "remove") {
var that = this;
// trigger another change which is not an "add"
// or "remove" or "itemchange" action
setTimeout(function () {
that.trigger("change");
}, 5);
}
});
}
});
var viewModel = kendo.observable({
wares: new CoolObservableArray([
{title: "hampton sofa", price: 989}
])
});
kendo.bind("#waresWrapper", viewModel);