Gre*_*egg 2 grails knockout.js
我正在尝试逐渐将KnockoutJS洒入我现有的应用程序中.我对此的第一个尝试是采用一些小的现有表单,并将其值推送到服务器上模糊以及通过绑定更新一些元素.
我遇到的问题是,当表单首次显示时,它不会通过knockout填充.我正在使用表单中已有的数据呈现页面.所以我设置我的淘汰赛:
function DomainViewModel() {
this.name = "";
this.description = "";
}
ko.applyBindings(new DomainViewModel());
Run Code Online (Sandbox Code Playgroud)
我有这样的形式:
<input data-bind="value: name" value="${domainInstance.name.encodeAsHTML()}"/>
<textarea data-bind="value: description" >${domainInstance.description.encodeAsHTML()}</textarea>
Run Code Online (Sandbox Code Playgroud)
所以正在发生的是我的表单被显示然后knockout将ViewModel中的值应用到表单中,这会消除服务器放置的值.我理解为什么会发生这种情况并且这不是一个错误.但是,我想知道这里是否还有其他选择.
我知道我可以做以下事情:
function DomainViewModel() {
this.name = "${domainInstance.name}";
this.description = "${domainInstance.name}";
}
Run Code Online (Sandbox Code Playgroud)
但这需要我将一些javascript直接放在GSP中(我使用的是Grails)而不是外部脚本文件.
所以,你有几种方法可以做到这一点.首先,永远不要这样做
function DomainViewModel() {
this.name = "${domainInstance.name}";
this.description = "${domainInstance.name}";
}
Run Code Online (Sandbox Code Playgroud)
您的viewmodel刚刚变得不可重用.如果你想使用grails填充viewmodel,在页面上设置一些javascript对象,并将其传递到你的外部javascript文件viewmodel定义,就像这样(不要忘记让你的属性obsevables!):
var grailsData = {
name : "${domainInstance.name}",
description : "${domainInstance.name}"
};
...
function DomainViewModel(data) {
this.name = ko.observable(data.name);
this.description = ko.observable(data.description);
}
ko.applyBindings(new DomainViewModel(grailsData);
Run Code Online (Sandbox Code Playgroud)
我建议使用这种方法,因为稍后当您更改数据源时,您不必更改HTML.但是,还有另一种选择.您可以创建一个从元素中收集值的绑定,并使用它来设置初始可观察值.该绑定可能如下所示:
ko.bindingHandlers.valueWithInit= {
init: function(element, valueAccessor) {
valueAccessor()(element.value);
},
update: function(element, valueAccessor) {
var value = valueAccessor();
element.value = ko.utils.unwrapObservable(value);
}
};
Run Code Online (Sandbox Code Playgroud)
这是演示这种方法的小提琴