Knockout嵌套视图模型

Mar*_*nce 17 javascript knockout.js

我坚持一定是一个简单的解决方案.我正在使用带有嵌套视图模型的knockout.js,除了我的删除功能无法正常工作外,一切似乎都很好.它似乎是正确绑定,但是当我单击删除时它不会被触发.

为什么嵌套视图模型?长话故事,但基本上很多东西都需要在一个页面上!

所以这是代码:

HTML

<section class="mini-form-container">
    <form data-bind="submit: repeatGuest.addDate">
        <input type="date" data-bind="value: repeatGuest.previousStay"/>
        <button type="submit" class="button-secondary ">Add date</button>
    </form>
    <div data-bind="foreach: repeatGuest.dates, visible: repeatGuest.dates().length > 0">
        <div>
            <input data-bind="value: date" disabled="disabled"  />
            <a data-bind="click: $parent.removeDate">Remove</a>
        </div>
    </div>
</section>

<section>
    <div data-bind="text: ko.toJSON($data)"></div>
</section>
Run Code Online (Sandbox Code Playgroud)

使用Javascript

function RepeatGuest() {
    /// <summary>Child View Model</summary>
    this.dates = ko.observableArray();
    this.previousStay = ko.observable();
}

RepeatGuest.prototype.addDate = function () {
        var self = this.repeatGuest;
        if (self.previousStay()) {
            self.dates.push({
                date: self.previousStay()
            });
        }
    };

RepeatGuest.prototype.removeDate = function (date) {
    this.dates.remove(date);
}

function ViewModel() {
    var self = this;
    self.repeatGuest = new RepeatGuest();
}
ko.applyBindings(new ViewModel());
Run Code Online (Sandbox Code Playgroud)

这是我的小提琴:http://jsfiddle.net/6Px4M/2/

那么为什么我的删除功能不会被解雇?

可能的问题:嵌套视图模型是错误的路径进入淘汰赛,似乎没有太多的信息吗?

RP *_*yer 24

使用这样的嵌套模型的最佳方法之一是使用with绑定.你可以做:

<div data-bind="with: repeatGuest">
   ...
</div>
Run Code Online (Sandbox Code Playgroud)

现在,范围是您的repeatGuest,您可以直接绑定其属性.

您的remove功能问题与当时的价值this和当时的人有关$parent.执行的函数的值this等于当前范围.绑定remove函数时,作用域是date数组中的一个对象.

处理此问题的典型方法是确保您的函数始终使用正确的值this.这可以在绑定(非常难看)中完成,如:

<a data-bind="click: $parent.repeatGuest.removeDate.bind($parent.repeatGuest)">Remove</a>
Run Code Online (Sandbox Code Playgroud)

更好的选择是在RepeatGuest构造函数中将其绑定在视图模型中:

this.removeDate = this.removeDate.bind(this);
Run Code Online (Sandbox Code Playgroud)

这允许实现在原型上生存,并使用强制正确值的包装器在每个实例上覆盖它this.或者,如果您没有将它放在原型上,那么您可以使用该var self = this;模式并self在处理程序中使用.

http://jsfiddle.net/cNdJj/

  • @ ben336 - 问题不是函数在原型上,而是他试图在视图模型上绑定它(在这种情况下是`$ parent`)而不是在repeatGuest对象本身(`$ parent.repeatGuest)上绑定它`). (2认同)