18

我坚持必须是一个简单的修复。我正在使用带有嵌套视图模型的 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/

那么为什么我的删除功能没有被触发呢?

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

4

2 回答 2

24

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

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

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

您的remove职能问题与当时的价值this和身份有关$parent。函数以this等于当前作用域的值执行。绑定删除函数时,范围是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/

于 2013-03-01T17:40:05.043 回答
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);
    }
}
于 2013-03-01T17:35:10.550 回答