当数据将对象链接到表单时,我遇到了奇怪的行为,导致我重新质疑究竟是什么数据绑定?
基本上我有一个表单可以创建新公司并更新它们。实际的创建/更新是通过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属性的数据。
所以我的问题是我应该如何改变编写代码的方式,这样我才能在根对象和属性上实现数据绑定?
答案 0 :(得分:3)
您遇到的问题是因为在您的方案中,您有像Company.Name
这样的路径,您希望将数据链接到不仅包含叶属性的更改,还包括更改更高层中的对象的更改。路径(在本例中为公司)。
为此,您需要使用语法data-link="Company^Path"
。
请参阅本文档主题中的路径:叶子更改或深层更改部分: http://www.jsviews.com/#observe@deep
另请参阅本主题中的示例:带有普通对象和数组的JsViews示例:http://www.jsviews.com/#explore/objectsorvm。
以下是jsfiddle的更新,使用以下语法:https://jsfiddle.net/msd5oov9/2/。
BTW,FWIW,在使用{^{for}}
的修补程序中,您没有必要使用第二个模板 - 您也可以写下:
<form class="form-horizontal">
{^{for Company}}
...
<input type="text" data-link="Name" />
{{/for}}
</form>
要在下面的评论中回复您的后续问题,您可以关联任何&#39;块&#39;标签与模板。在标记上使用tmpl=...
意味着您已决定将块内容分成单独的可重用模板。 (A&#39;部分&#39;,如果你愿意的话)。该模板的数据上下文与块中的数据上下文相同。
具体而言,{{include}} {{if}}和{{else}}标记不会移动数据上下文,但{{for}}和{{props}}会移动数据上下文。使用自定义标签,您可以决定......
因此,在您的情况下,您可以使用{^{for Company tmpl=.../}}
或{{include tmpl=.../}}
,但在第二种情况下,您引用的其他模板将使用<input type="text" data-link="Company^Name" />
而不是<input type="text" data-link="Name" />
。
以下是一些相关链接:
答案 1 :(得分: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,因此,如果有人遇到此问题并希望了解此解决方案如何适用于他们的特定问题,他们将能够使用有效的解决方案。