6

当数据将对象链接到表单时,我遇到了奇怪的行为,这导致我重新质疑数据绑定的究竟是什么?

基本上我有一个创建新公司以及更新它们的表格。实际的创建/更新是通过 ajax 完成的,这就是为什么我为这两个目的使用相同的表单。在我必须创建一家公司的情况下,一切都按我的预期进行。但是,当我必须更新一家公司时,事情并不像我期望的那样工作。请看下面的代码。

这是我的示例表单 HTML:

<div id="result"></div>

<script type="text/x-jsrender" id="CompanyFormTemplate">
    <form>
        <input type="text" data-link="Company.Name" />
    </form>
</script>

这是我的 Javascript 代码:

var app = new CompanyFormContext();

function CompanyFormContext() { 
    this.Company = {
        Name: ''
    };

    this.setCompany = function (company) {
        if (company) {
            $.observable(this).setProperty('Company', company);
        }
    };
};

$(function () {
    initPage(); 

    ...

    if (...) {
        // we need to update company information

        app.setCompany({ Name: 'Company ABC' });
    }
});

function initPage() {
    var template = $.templates('#CompanyFormTemplate');
    template.link("#result", app);
}

它不是显示“公司 ABC”的表单输入,而是空的。但是,如果我在其中输入任何内容,那么 Company.Name 值确实会改变!但是,虽然我希望数据的输入绑定到我的 Company 对象的 Name 属性,但我还希望它知道对(父) Company 对象所做的任何更改,并相应地更新它的数据绑定到它的 Name 属性。

所以我的问题是我应该如何改变我编写这段代码的方式,以便我可以在根对象和属性上实现数据绑定?

4

2 回答 2

4

您遇到的问题是因为在您的场景中,您有类似Company.Name的路径,您希望将其数据链接到不仅叶属性的更改,而且还涉及涉及替换路径中较高对象的更改(在本例中为公司) .

为此,您需要使用语法data-link="Company^Path"

请参阅此文档主题中 的路径:叶子更改或深度更改部分:http: //www.jsviews.com/#observe@deep

另请参阅本主题中的示例,例如示例:具有普通对象和数组的 JsView :http : //www.jsviews.com/#explore/objectsorvm

这是使用该语法的 jsfiddle 的更新:https ://jsfiddle.net/msd5oov9/2/ 。

顺便说一句,FWIW,在您的修复中,{^{for}}您不必使用第二个模板 - 您也可以编写:

<form class="form-horizontal">
    {^{for Company}}
        ...
        <input type="text" data-link="Name" />
    {{/for}}
</form>

要在下面的评论中回复您的后续问题,您可以将任何“阻止”标签与模板相关联。在标签上使用tmpl=...意味着您已决定将块内容分离到单独的可重用模板中。(“部分”,如果你愿意的话)。该模板的数据上下文将与块内的数据上下文相同。

所以具体来说,{{include}} {{if}} 和 {{else}} 标签不会移动数据上下文,但 {{for}} 和 {{props}} 会。使用自定义标签,您可以决定...

因此,在您的情况下,您可以使用其中一种{^{for Company tmpl=.../}}{{include tmpl=.../}}但在第二种情况下,您引用的其他模板将使用<input type="text" data-link="Company^Name" />而不是<input type="text" data-link="Name" />.

以下是一些相关链接:

于 2015-05-19T16:26:19.563 回答
1

我发现了一种方法来实现这一点。起初它可能看起来很复杂,但一旦你正确理解它就会有意义。

(PS:我希望有这样的样本。我可能只是写博客。)

HTML 标记:

<script type="text/x-jsrender" id="CompanyFormTemplate">
    <form>
        {^{for Company tmpl="#CompanyDetailsTemplate" /}
    </form>
</script>

<script type="text/x-jsrender" id="CompanyDetailsTemplate">
    <input type="text" data-link="Name" />
</script>

Javascript:不需要对上面的代码进行任何更改。


好的,正如我所说,解决方案可能看起来很复杂,但事实证明,我真正需要做的就是首先在 Company 对象上设置数据绑定,然后再到它的属性对象。我想知道是否有更优雅的解决方案(即,所有这些都可以在单个模板中实现)但是该解决方案确保数据绑定发生在父对象及其属性上。

我已经为这个解决方案发布了一个JsFiddle,所以如果有人遇到这个问题并想了解这个解决方案如何解决他们的特定问题,他们将能够使用一个有效的解决方案。

于 2015-05-19T08:08:16.547 回答