2016-06-29 32 views
1

我在Knockout中建立了一組過濾器,並希望將當前的過濾器設置存儲在對象上。如果有任何更改,我需要過濾我的數據。KnockoutJS觀察對象的可觀察對象

即使Filter對象發生更改,也不會觸發訂閱self.filter。這可以觀察到嗎?

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>

回答

1

filter不會改變,這就是爲什麼訂閱功能不被打到。但是,和role的可觀測量filter變化。當性別下拉改變時,self.filter().gender.subscribe()將被調用。 self.filter.subscribe()將被調用的唯一方法是如果您更改過濾器本身的值,例如self.filter(new Filter())

如果filter只有可觀察的屬性(除非您要像上例中那樣創建新的過濾器,而不是僅僅改變其屬性),那麼沒有多大意義。

+0

要小心創建大量的訂閱,儘管(他們四處閒逛並且_will_會使用內存 - 隨着時間的推移,SPA可能會受到很大影響) - 理論上你需要在「filter」_does_ change時訂閱 - 此時你應該可能還會從之前的「過濾器」值中處理訂閱。 –

+0

@JamesThorpe哦!我之前正在查找內存泄漏,將檢查其他訂閱。 – PeterB

+0

@PeterB如果你的頁面生存的時間不長,確保每個'subscribe'的返回值都存儲在某個地方,並且相應地調用['dispose''](http:// knockoutjs。 com/documentation/observables.html#highlighter_397069)在正確的時間使用。 –