我正在使用Knockout和jQuery和jQuery模板。假设我有一个期望人物对象的模板
<script type="text/html" id="person_template">
<tr><td>Forename</td><td><input type="textbox" data-bind="value:FORENAME" /></td></tr>
<tr><td>Surname</td><td><input type="textbox" data-bind="value: SURNAME"/></td></tr>
</script>
现在,如果我将只有FORENAME的对象传递给此模板,我将收到错误:
SURNAME未定义错误
我试图在Knockout中创建一个自定义绑定,但是在它到达之前就会抛出错误。
如果我在将对象传递给模板之前填写这些空字段,我知道一切都会成功,但我想在我的模板中而不是在我的javascript中使用解决方案。
有没有人知道一种方法可能会对这些情况有所帮助?
答案 0 :(得分:2)
这有点挑战,因为你在模板中。在准备模板时,KO访问变量(实际上,它是通过KO构建的函数在jQuery模板中访问的)。
一种选择是将您的属性作为字符串传递给自定义绑定,并确保它已初始化。
就像是:
ko.bindingHandlers.valueWithInit = {
init: function(element, valueAccessor, allBindingsAccessor, context) {
var value = valueAccessor();
if (!context[value]) {
context[value] = ko.observable();
}
var realValueAccessor = function() {
return context[value];
}
//call the real value binding
ko.bindingHandlers.value.init(element, realValueAccessor, allBindingsAccessor, context);
},
update: function (element, valueAccessor, allBindingsAccessor, context) {
var realValueAccessor = function() {
return context[valueAccessor()];
}
//call the real value binding
ko.bindingHandlers.value.update(element, realValueAccessor);
}
}
因此,这将验证您的对象是否具有该字段,如果不是,则为该字段创建新的observable。然后,它将其交给真正的价值绑定。
一个非常类似(但不那么详细)的替代方法是让绑定确保字段在那里,然后重写绑定属性以使用真正的value
绑定。类似的东西:
//Another option: rewrite binding after making sure that it is initialized
ko.bindingHandlers.valueWithInit = {
init: function(element, valueAccessor, allBindingsAccessor, context) {
var value = valueAccessor();
if (!context[value]) {
context[value] = ko.observable();
}
$(element).attr("data-bind", "value: " + value);
ko.applyBindings(context, element);
}
}
这两个假设您传递的字段直接位于作为模板上下文的对象之外(因此,如果您传递具有全局范围的内容,如'viewModel.someProperty',则无效)。
以下是两个选项的工作示例:http://jsfiddle.net/rniemeyer/dFSeB/
我宁愿不把这个字段作为一个字符串传递,但是我看到它并没有真正的好方法。
答案 1 :(得分:0)
最好确保传递给模板的对象设置了所有参数。如果不是,那么您可以添加默认值,但将所有这些逻辑放在模板中是违反MVVM模式的。模板(如mvc中的视图)不应包含任何逻辑IMO。