user2643709
user2643709

Reputation: 117

Knockout binding on foreach item not updating

I am using the click event on a button to set the value of an item that was generated using a foreach.

<table>
   <tbody data-bind="foreach: Employees">
   <a  data-bind="click:$parent.delete()">
..

in my delete function I am setting the value but it doesn't update the screen

 Delete :(emp) {
  emp.active=false;
}

When I create I am setting all the individual properties as observable but seems like they are not when in the foreach loop.

Employees is filtered.computed

var Employees=ko.computed(function() {
 return ko.utils.arrayFilter(AllEmployees(), function (empid) {
            return empid.ID == filter();
        });

Upvotes: 4

Views: 6007

Answers (3)

PW Kad
PW Kad

Reputation: 14995

Knockout subscribes to the observable array, but not to each observable within that array. If you want to subscribe to individual properties you need to subscribe manually by using myObservable.subscribe()

Knockout subscribes to the observable array, but not to each observable within that array. If you want to subscribe to individual properties you need to subscribe manually using myObservable.subscribe()

Edit

If you are trying to have your computed keep track of what should be in your computed you can do so like this -

var allEmployees = ko.observableArray([my data goes here]);

var Employees=ko.computed(function() {
 return ko.utils.arrayFilter(allEmployees(), function (emp) {
            return emp.active === true;
        });
});

That works if active is not an observable property of each allEmployees(). If it is an observable just change that to -

var allEmployees = ko.observableArray([my data goes here]);

var Employees=ko.computed(function() {
 return ko.utils.arrayFilter(allEmployees(), function (emp) {
            return emp.active();
        });
});

Upvotes: 0

Josh
Josh

Reputation: 44906

When you get/set observables you need to call them like this:

var val = obj.prop(); //Getter
obj.prop(false); //Setter

One other issue you have is that you are using parenthesis in your click binding. Remember that Knockout bindings are just javascript, so it will actually execute that expression when it binds.

You need to get rid of those parenthesis or emp will be undefined initially.

UPDATE:

I've updated this jsFiddle to include three filtered lists similar to what you have shown above. You can see that using a filtered list via a computed has no bearing on how knockout handles the bindings, and the UI updates seamlessly.

http://jsfiddle.net/jwcarroll/ceRPK/

Upvotes: 2

Michael Best
Michael Best

Reputation: 16688

To set an observable, you have to call it (since observables are implemented as functions):

emp.active(false);

Your method simply overwrites the observable.

Upvotes: 1

Related Questions