javascript 敲除嵌套视图模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15163354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 23:43:50  来源:igfitidea点击:

Knockout nested view model

javascriptknockout.js

提问by Marvin

I'm stuck with what must be a simple fix. I am using knockout.js with nested view models, and all seems fine except that my remove function is not working correctly. It appears to be binding correctly, however it is not fired when I click remove.

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

Why nested view models? Long story, but essentially a lot of stuff is required to be on one page!

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

So here is the code:

所以这里是代码:

HTML

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

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

And here is my fiddle: http://jsfiddle.net/6Px4M/2/

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

So why isn't my remove function getting fired?

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

Possible side question: is nested view models the wrong path to take in knockout, there doesn't seem to much info on this?

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

回答by RP Niemeyer

One of the best ways to work with a nested model like this is to use the withbinding. You can do:

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

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

Now, the scope is your repeatGuestand you can bind directly against its properties.

现在,作用域是你的repeatGuest,你可以直接绑定它的属性。

The issue with your removefunction is related to the value of thisand who $parentis at that time. Functions are executed with a value of thisthat is equal to the current scope. When your remove function is bound, the scope is one of the objects in the datearray.

你的remove职能的问题与当时的价值this和谁有关$parent。函数以this等于当前作用域的值执行。当您的 remove 函数被绑定时,作用域是date数组中的对象之一。

The typically way to handle this is to make sure that your function is bound to always use the correct value of this. This could be done in the binding (very ugly) like:

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

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

A better option is to bind it in the view model, in your RepeatGuestconstructor:

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

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

This allows the implementation to live on the prototype and overwrites it on each instance with a wrapper that forces the correct value of this. Alternatively, if you do not put it on the prototype, then you can use the var self = this;pattern and use selfin the handler.

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

http://jsfiddle.net/cNdJj/

http://jsfiddle.net/cNdJj/

回答by Ben McCormick

The binding won't access the function on the wrong prototype. You're binding to the viewModel, not to the RepeatGuest object right now.

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

It works if you set it as a local function:

如果您将其设置为本地函数,它会起作用:

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

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

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