2016-10-03 68 views
1

我继续学习挖空并继续面对奇怪的问题我不知道如何克服。在循环中敲除嵌套绑定

我有以下的HTML页面和JS脚本:

HTML:

<div data-bind="debug: $data, foreach: objects"> 
    <span hidden="hidden" data-bind="value: type.id"></span> 
    <input type="text" data-bind="value: type.title" /> 
    <button type="button" data-bind="click: $parent.removeObject">- </button> 
    </div> 
    <div class="control-group form-inline"> 
    <select data-bind="options: availableTypes, optionsValue: function(item) {return item;}, 
         optionsText: function(item) {return item.title;}, value: itemToAdd.type, 
         optionsCaption: 'Select types...'"></select> 
    <button type="button" data-bind="click: addObject">+</button> 
    </div> 
</div> 

JS:

function model() { 
    var self = this; 

    var types = [new Type("1"), new Type("2"), new Type("3")]; 
    var objects = [new Object("1")]; 

    self.objects = ko.observableArray(objects); 

    self.usedTypes = ko.computed(function() { 
    return types.filter(function(type) { 
     for (var j = 0; j < self.objects().length; j++) { 
     if (self.objects()[j].type.id === type.id) { 
      return true; 
     } 
     } 
     return false; 
    }); 
    }, self); 

    self.availableTypes = ko.computed(function() { 
    return types.filter(function(type) { 
     for (var j = 0; j < self.usedTypes().length; j++) { 
     if (self.usedTypes()[j].id === type.id) { 
      return false; 
     } 
     } 
     return true; 
    }); 
    }, self); 

    self.itemToAdd = new Object(); 

    self.addObject = function() { 
    self.objects.push(self.itemToAdd); 
    self.itemToAdd = new Object(); 
    }; 

    self.removeObject = function(object) { 
    self.objects.remove(object); 
    }; 
}; 

function Object(type) { 
    var self = this; 
    self.type = new Type(type); 
} 

function Type(id) { 
    var self = this; 
    self.id = id; 
    self.title = id; 
} 
ko.applyBindings(new model()); 

我简化模型来显示错误。事情是,淘汰赛声称这是非法的呼吁做到这一点:
<span hidden="hidden" data-bind="value: type.id"></span>
因为它不能在上下文中找到属性id。据我所知,它在那里,一切都好。

请问有人能指出我的错误吗?

p.s.这里是一个JsFiddle

加成
感谢@ Daryl的帮助下,我才得以本地化问题。如果我更换

self.itemToAdd = new Object(); 

    self.addObject = function() { 
    self.objects.push(self.itemToAdd); 
    self.itemToAdd = new Object(); 
    }; 

有:

self.itemToAdd = new Object(); 

    self.addObject = function() { 
    self.objects.push(new Object(1)); 
    self.itemToAdd = new Object(); 
    }; 

不过,下面的代码仍然不工作:

self.itemToAdd = new Object("1"); 

    self.addObject = function() { 
    self.objects.push(self.itemToAdd); 
    self.itemToAdd = new Object(); 
    }; 

看来itemToAdd对象从它绑定到HTML元素误填。但我仍然不知道究竟是什么错误。

+0

从你的小提琴判断,它似乎正在加载一切正常 - 它只是当你试图添加一个新的对象,它抱怨。我的猜测是,这是由于你的addObject方法的工作原理。你可以看到它推着self.itemToAdd,它总是被初始化为一个空的Object,因为你没有传入类型参数。由于你没有传入类型参数,所以你的Type对象的属性被初始化为一个初始值未定义的值。尝试传递一个“1”“2”或“3”到你的对象构造函数,看看它的行为如何你所期望的。 – Daryl

+0

@Daryl,谢谢你的回复。我试图做你的建议,但结果很奇怪,他们不帮我解决这个问题。我会相应地更新这篇文章。 –

回答

0

您已允许您的类型下拉列表未设置。当淘汰赛显示标题时,它将清除实际值。这意味着,通过渲染UI,您的itemToAdd.type被清除。

第二种方法通过不使用数据绑定实例来解决此问题。

此外:

  • 我不会覆盖Object构造,如果我是你...找一个不同的名称。
  • 如果您想对UI进行双向绑定,请确保您的itemToAdd具有可观察的属性。