Reputation: 1397
I have the below array bound to a template
function Customer(id, name){
this.Id = ko.obserable(id);
this.Name = ko.obserable(name);
}
var customer1 = new Customer(1, "a");
var customer2 = new Customer(2, "b");
var customers = [customer1, customer2];
var oa = ko.observableArray(customers);
oa.subscribe(function(newValues){
//How to force trigger this when a customer property gets updated?
});
When I update a customer name on the view, the array has the updated data, but it does not notify it's subscribers. How do I get around that and force notify its subscribers?
Upvotes: 1
Views: 39
Reputation: 23372
You can use computed
values to automatically track changes in a list of values. Every observable you unwrap inside the computed function will create a dependency.
The only downside: you won't know which change caused the update. If that's what you need, you need to subscribe to the individual Name
observables.
Here's an example that uses a custom equality comparer to keep things tidy. You can also only have hash
return a string
and unwrap oa
inside the subscriber method manually.
function Customer(id, name){
this.Id = ko.observable(id);
this.Name = ko.observable(name);
this.toString = () => `(${this.Id()}) ${this.Name()}`;
}
var customer1 = new Customer(1, "a");
var customer2 = new Customer(2, "b");
var customers = [customer1, customer2];
var oa = ko.observableArray(customers);
var oaHash = ko.pureComputed(() => ({
hash: oa().map(c => c.Name()).join("||"),
newValues: oa()
}));
oaHash.equalityComparer = (a, b) => a === b || a && b && a.hash === b.hash;
oaHash.subscribe(function ({ newValues }) {
console.log(
"Something changed, I now contain:",
newValues.map(c => c.toString()).join(", ")
);
});
customer1.Name("Jane");
oa.push(new Customer(3, "c"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Upvotes: 1