PeterB
PeterB

Reputation: 2329

KnockoutJS observing object of observables

I am building a set of filters in Knockout and want to store the current filter settings on an object. When any is changed, I need to filter my data.

The subscription to self.filter is never triggered, even though the Filter object changes. Can this be observed?

var Filter = function() {
    this.gender = ko.observable("");
    this.role = ko.observable("");
};
viewModel = function() {
  var self = this;
  self.filter = ko.observable(new Filter());
  self.filter.subscribe(function(obj) {
    console.log("The filter has been modified! (this line never runs)", obj);
  });
  
  self.output = function() { console.log("Gender", self.filter().gender(), "Role", self.filter().role());}
};

vm = new viewModel();
ko.applyBindings(vm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>


<select data-bind="value: filter().gender">
  <option value="">Male or Female</option>
  <option value="M">Male</option>
  <option value="F">Female</option>
</select>
<select data-bind="value: filter().role">
  <option value="">Any</option>
  <option value="Student">Student</option>
  <option value="Guest">Guest</option>
</select>

<p>
<button data-bind="click: output">
Output Filter values (to prove the object is updated)
</button>
</p>

Upvotes: 1

Views: 484

Answers (1)

Paul Abbott
Paul Abbott

Reputation: 7211

The filter does not change, which is why the subscription function doesn't get hit. The gender and role observables of the filter do change, however.

self.filter().gender.subscribe() will get called when the gender dropdown changes. The only way self.filter.subscribe() will get called is if you change the value of the filter itself, for example self.filter(new Filter()).

There is not much point to making filter observable if all it is going to have is observable properties (unless you are going to create new filters like in the example above instead of just changing its properties).

Upvotes: 1

Related Questions