Mark Robinson
Mark Robinson

Reputation: 13278

How to create a custom binding for an observableArray

Okay, the title of the question kind of suggests one solution I've been considering but here is my issue and I'm open to suggestions.

I have a view model similar to this (although VASTLY simplified):

var viewModel = {
    items: ko.observableArray([new Person('fred'), new Person('Joe')]),
    name: ko.observable('hello world')  
};

function Person(name)
{
    this.Name = ko.observable(name);
    this.Parent = ko.observable();
}
ko.applyBindings(viewModel);

Whenever a Person is added to items I want to automatically set it's Parent property to the thing it is being added to. (In my real application, this is a deeply hierarchical structure so I can't just hardcode the parent).

I was considering writing a customer binding to make my own observableArray. Whenever anything was added to it, the custom binding would set the Parent property. I've looked at http://knockoutjs.com/documentation/custom-bindings.html but this seems to only deal with normal observable properties.

So how would I do this or is there a better way of achieving this that I am missing?

Thanks!

Upvotes: 0

Views: 1038

Answers (1)

Ewout
Ewout

Reputation: 346

A custom binding would be the wrong thing to do. The binding determines how an observable is bound to a DOM element, for example the value binding will keep the value of a form field in sync with an observable, the visible binding will hide or show a DOM element depending on the observable's value.

The fact that you are setting a property on the Person when it is added to a collection is an implementation detail your user interface should not know about. My suggestion would be to subscribe to the observableArray and set the Parent property manually when a Person is added. In code:

 viewModel.items.subscribe(function(new_array) {
   for (var i=0 ; i < new_array.length ; ++i) {
     if (!new_array[i].Parent())
       new_array[i].Parent(items);
   }
 }

Upvotes: 6

Related Questions