【发布时间】:2015-04-05 10:11:42
【问题描述】:
我不太擅长淘汰 js,所以我可能错过了一些东西。
我的用例:
我有一个简单的视图模型。我的页面看起来像这样
<body>
<hr />
<div>
<label for="">
Basic :</label>
<input type="text" name="" data-bind="value: basic" id="txtBasic" />
</div>
<div>
<label for="">
HRA :</label>
<input type="text" name="" data-bind="value: hra" id="txtHra" />
</div>
<div>
<div style="background-color:silver;">
<hr />
<label for="">
<input type="button" data-bind="click : generateModelValue" value="Generate Runtime Property" />
<input type="button" data-bind="click : tryRebind" value="Try Rebinding with clean node" />
<br>
DA :</label>
<input type="text" name="" id="txtDa" data-bind="value: $data.da"><br><br></div>
</div>
<hr />
<div>
<label for="">
Tax :</label>
<input type="range" name="" id="rangeTax" min="0" max="30" value="0" data-bind="value: tax" />
<span id="spanTax">[Tax%]</span>
</div>
<div>
<input type="button" value="Calculate" id="btnCalculate" data-bind="click: computeSalary" />
</div>
<div>
<div id="divResult" data-bind="text: salary">
[Salary]</div>
</div>
</div>
<script>
myViewModel={
basic: ko.observable(1000),
hra: ko.observable(10),
tax: ko.observable(10),
salary: ko.observable('Yet to be calculated'),
computeSalary: function () {
this.salary(this.basic()+this.da()+this.hra());
},
generateModelValue: function () {
debugger;
this.da=ko.observable("123");
},
tryRebind: function () {
debugger;
alert("Why do i have to call this to update the view model");
ko.cleanNode($('body')[0]);
ko.applyBindings(myViewModel,$('body')[0]);
}
};
ko.applyBindings(myViewModel,$('body')[0]);
</script>
</body>
我想在运行时添加一个属性(在本例中为“da”)。因此,为了使示例易于阅读,我将在我的模型上调用“generateModelValue”函数,该函数将添加“myViewModel”上的“da”属性,样本值为“123”。
这成功地创建了一个新的 observable 属性(我检查了 console.log)。 但不更新 UI。
所以在单击之后,我在视图模型上调用了另一个函数,该函数将尝试执行 ko.cleanNode($('body')[0]) 后跟 ko .applyBindings(myViewModel,$('body')[0]); 然后更新 UI。
我的问题:
我必须调用干净节点还是有更好的方法可以在视图模型更新后立即更新 UI?
我的疑惑:
- 我不认为使用干净节点是实现此目的的好方法吗?
- 如果对象太复杂或太大,是否会导致任何性能问题。
- 我正在使用
"<input type="text" name="" id="txtDa" data-bind="value: $data.da">"在我的 HTML 中(这样当我使用 viewModel 中不可用的属性调用 applyBinding 时不会引发未定义的错误)
真的需要$data(还有其他选择吗?)
访问过的帖子:
Adding properties to the view model created by using the Knockout JS mapping plugin
(我不太确定我是否理解这篇文章。如果推荐的话会再看一遍,因为我也使用映射插件将纯 json 响应从 AJAX 调用转换为可观察视图模型,但我的实现是有点不同)
Live Plunker: http://plnkr.co/edit/4EwSdKihVak1dGhuobbi?p=preview
已编辑:
为什么我需要实现这一点-
因为在我调用 ko.applybinding 时,我的 viewModel 总是小于我的 HTML 标记中所需的数据绑定属性,因此会抛出未定义的错误(我使用了 $data以避免此错误)。
因此,在 ko.applyBinding(html-element) 中传递的最终 html 视图将是构成屏幕的几个较小的 html sn-ps 的 UNION。
并且不可能在调用应用绑定时收集所有视图模型属性,因为视图模型的复杂性会随着用户交互(Ajax 调用)而增加
我希望它清楚。如果没有,我正在为此创建一个 plunkr。很快就会更新。
更新
新plunkr
http://plnkr.co/edit/8PNHk25jl2xig0GLyqQq?p=preview
在上面的 plunkr 中带有
的部分<div data-bind="visible: $data.da">
You will see this section only if the da property is available on the view model
</div>
将在应用绑定时存在于 DOM 中,但 “da”的值不会。 并且在某些用户交互之后,视图模型将被更新,因为对象将通过 ajax 调用接收新属性(例如 plunkr 上的 tha 中的 da)。因此将显示 da 部分。
【问题讨论】:
标签: javascript model-view-controller knockout.js viewmodel knockout-mapping-plugin