Knockout嵌套视图模型

时间:2013-03-01 17:23:30

标签: 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>

的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());

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

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

可能存在的问题:嵌套视图模型是否需要在淘汰中采取错误的路径,这似乎没有太多信息?

2 个答案:

答案 0 :(得分:24)

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

<div data-bind="with: repeatGuest">
   ...
</div>

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

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

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

<a data-bind="click: $parent.repeatGuest.removeDate.bind($parent.repeatGuest)">Remove</a>

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

this.removeDate = this.removeDate.bind(this);

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

http://jsfiddle.net/cNdJj/

答案 1 :(得分:4)

绑定不会访问错误原型上的函数。您现在绑定到viewModel,而不是RepeatGuest对象。

如果将其设置为本地函数,则可以正常工作:

http://jsfiddle.net/6Px4M/3/

function ViewModel() {
    var self = this;
    self.repeatGuest = new RepeatGuest();
    self.removeDate = function (date) {
        self.repeatguest.dates.remove(date);
    }
}