TrentVB
TrentVB

Reputation: 428

Getting property from knockoutjs observablearray with id

I'm trying to look up a value in an observable array using the value of a property of one of the items. Here is some example code:

HTML:

<ul data-bind="foreach: items">
  <li data-bind="text:name"></li>
  <li>Cousin: <span data-bind="text:related_id"></span></li>
</ul>​

JS:

var item = function (data){
  this.id = ko.observable(data.id);
  this.name = ko.observable(data.name);
  this.related_id = ko.observable(data.related_id);
}

var related_item = function(data){
  this.id = ko.observable(data.id);
  this.name = ko.observable(data.name);
}

var ViewModel = function(){
    this.items = ko.observableArray([
      new item({id:1,name:'thing1',related_id:1}),
      new item({id:2,name:'thing2',related_id:2})                
    ]);

this.related_items = ko.observableArray([
    new related_item({id:1,name:'cousin it'}),
    new related_item({id:2,name:'cousin fred'})
]);
}
ko.applyBindings(new ViewModel);

Fiddle with code above: fiddle

My question: What is the best way to get the related_item's name property to show where the item's related_id is currently being shown? ​

Upvotes: 2

Views: 2811

Answers (1)

Jensen Ching
Jensen Ching

Reputation: 3164

Something like this JSFiddle here: Fiddle

What I did was put the item and related_item "objects" into the ViewModel so that I could reference them. There are 2 possible solutions:

  1. Pass the related_item itself into the item object instead of just the id.
  2. Iterate through the related_items array.

JS:

    self.item = function (data){
        var itm = this;
        itm.id = ko.observable(data.id);
        itm.name = ko.observable(data.name);
        itm.related_id = ko.observable(data.related_id);
        //Possible solution 1
        itm.related_item = ko.observable(data.related_item); 
        //Possible solution 2
        itm.related_item_name = ko.computed(function() {
            tmp = '';
            $.each(self.related_items(), function(idx, elem) {
                if (elem.id() === itm.related_id()) {
                    tmp = elem.name();
                    return false; //break out of the $.each loop
                }
            });
            return tmp;
        });
    };

HTML:

<ul data-bind="foreach: items">
<li data-bind="text:name"></li>
   <li>Cousin: <span data-bind="text:related_id"></span></li>
   <li>(soln 1) Cousin: <span data-bind="text:related_item().name()"></span></li>
   <li>(soln 2) Cousin: <span data-bind="text:related_item_name"></span></li>
</ul>​

If you have no other constraints, I'd just rather do the first method and pass the entire object in instead of the ID.

Upvotes: 2

Related Questions