敲除嵌套视图模型 [英] Knockout nested view model

查看:16
本文介绍了敲除嵌套视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

代码如下:

HTML

<form data-bind="提交:repeatGuest.addDate"><input type="date" data-bind="value: repeatGuest.previousStay"/><button type="submit" class="button-secondary">添加日期</button></表单><div data-bind="foreach:repeatGuest.dates,可见:repeatGuest.dates().length>0"><div><input data-bind="value: date" disabled="disabled"/><a data-bind="click: $parent.removeDate">Remove</a>

</节><部分><div data-bind="text: ko.toJSON($data)"></div></节>

Javascript

function RepeatGuest() {///<summary>子视图模型</summary>this.dates = ko.observableArray();this.previousStay = ko.observable();}RepeatGuest.prototype.addDate = function () {var self = this.repeatGuest;如果(self.previousStay()){self.dates.push({日期:self.previousStay()});}};RepeatGuest.prototype.removeDate = 函数(日期){this.dates.remove(date);}函数视图模型(){var self = this;self.repeatGuest = new RepeatGuest();}ko.applyBindings(new ViewModel());

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

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

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

解决方案

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

...

现在,范围是您的 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/

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.

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

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

And here is my fiddle: 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?

解决方案

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

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

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

The issue with your remove function is related to the value of this and who $parent is at that time. Functions are executed with a value of this that is equal to the current scope. When your remove function is bound, the scope is one of the objects in the date array.

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:

<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 RepeatGuest constructor:

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 self in the handler.

http://jsfiddle.net/cNdJj/

这篇关于敲除嵌套视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆