请在此处查看:JSFiddle
这是html:
<script src="http://code.jquery.com/jquery-2.1.4.min.js" ></script>
<div id="first">
<button data-bind="click: toggleColumn">Click me!</button>
</div>
<ul id="list_test">
<!-- ko foreach: list -->
<li data-bind="text: $data.ColName"></li>
<!-- /ko -->
</ul>
这是javascript:
function ViewModel(){
var self = this;
self.showColumn = ko.observable(true);
self.toggleColumn = function(){
self.showColumn(!self.showColumn());
};
self.ListOfObjects = [
{ColName: 'test1', visible: self.showColumn},
{ColName: 'test2'},
{ColName: 'test3', visible: self.showColumn},
{ColName: 'test4'},
{ColName: 'test5'},
];
};
function TestViewModel(params){
var self = this;
self.list = ko.observableArray();
for(var i = 0; i < params.length; i++){
var obj = params[i];
if(!obj.visible){
//obj.visible = ko.observable(true);
}
if(obj.visible){
obj.visible.subscribe(function(){
var elements = $('li');
for(var i = 0; i < elements.length; i++){
if($(elements[i]).text() == obj.ColName){
$(elements[i]).hide();
}
}
});
}
self.list.push(obj);
}
}
function initViewModel(){
var mod = new ViewModel();
ko.applyBindings(new TestViewModel(mod.ListOfObjects),document.getElementById("list_test"));
ko.applyBindings(mod, document.getElementById("first"));
}
initViewModel();
所以我的问题是这个。为什么当你点击按钮时,&#39; test5&#39;列表项被隐藏而不是两个订阅对象(test1和test3)?似乎总是默认隐藏列表的末尾。
我用我的实际代码完成了这个,因为JSFiddle只是错误的准系统复制,我通过Chrome的控制台/调试器检查了所有内容。
在subscribe调用中,与showColumn变量相比,obj.visible属性不是同一个实例。如果你在订阅调用中的obj.visible上获得了SUBscriptionsCount,那么你只能获得一个它应该永远不会获得的订阅,因为它永远不会被定义。如果你在&#39; test1&#39;和&#39; test3&#39;您可以获得2个订阅的可见属性(如预期的那样),它们是与ViewModel.showColumn相同的实例的引用。
仍然在订阅中,如果你检查obj的值,你就会得到
{ColName: 'test5', visible: /*some knockout obj*/}
它永远不应该从&#39; test5&#39;中调用subscribe。它应该来自&#39; test1&#39;和&#39; test3&#39;。
现在,如何通过&#39; item5&#39;来通知obj.visible.subscribe。当&#39; item5&#39;对象从未收到对ViewModel.showColumns的引用?如何为&item 39&#39;?
定义可见性对我而言,它看起来像是对另一个ko.observable对象的订阅通知订阅完全不同(甚至不存在)ko.observable。我很确定不应该发生......
答案 0 :(得分:1)
这是一个经典的&#34;关闭&#34;错误。您的obj
变量在for
循环的生命周期内发生变化,其所持有的最后一个值指向&#34; test5&#34;。事件处理函数使用相同的变量,因此当事件被触发时,它会查找&#34; test5&#34;并隐藏。您可以使用标准闭合和解决方案解决这个问题IIFE。
这是重要的代码:
if(obj.visible){
(function (obj) {
obj.visible.subscribe(function(){
var elements = $('li');
for(var i = 0; i < elements.length; i++){
if($(elements[i]).text() == obj.ColName){
$(elements[i]).hide();
}
}
});
})(obj);
}
这是一个固定的fiddle。