Javascript 为HTML标记中的可观察对象提供初始值
我试图创建一个Javascript 为HTML标记中的可观察对象提供初始值,javascript,data-binding,knockout.js,observable,Javascript,Data Binding,Knockout.js,Observable,我试图创建一个HtmlHelper扩展,将一些HTML输出到视图中。在这个HTML中,我连接了一些KnockoutJS绑定。我是KO的新手,所以我仍然在努力完成一些事情。无论如何,我要做的是在客户端代码上生成绑定到可观察对象的输入字段(在服务器端代码中),然后通过隐藏字段的值设置可观察对象的初始值。不幸的是,这对我不起作用。因此,我想知道是否有任何方法可以让我做到这一点(即使我必须做完全不同的事情) 我基本上是这样做的: 在我的客户端视图模型中,我有以下内容: self.dataSource =
HtmlHelper
扩展,将一些HTML输出到视图中。在这个HTML中,我连接了一些KnockoutJS绑定。我是KO的新手,所以我仍然在努力完成一些事情。无论如何,我要做的是在客户端代码上生成绑定到可观察对象的输入字段(在服务器端代码中),然后通过隐藏字段的值设置可观察对象的初始值。不幸的是,这对我不起作用。因此,我想知道是否有任何方法可以让我做到这一点(即使我必须做完全不同的事情)
我基本上是这样做的:
在我的客户端视图模型中,我有以下内容:
self.dataSource = ko.observable();
self.pageSize = ko.observable();
<input type="hidden" value="/Employee/Get" data-bind="value: dataSource" />
<input type="hidden" value="30" data-bind="value: pageSize" />
我的扩展方法输出以下内容:
self.dataSource = ko.observable();
self.pageSize = ko.observable();
<input type="hidden" value="/Employee/Get" data-bind="value: dataSource" />
<input type="hidden" value="30" data-bind="value: pageSize" />
但是当页面呈现时,当我检查元素时,我注意到输入字段的
值
被设置为空字符串,我认为这是因为可观察对象的声明方式。但是有没有一种方法可以覆盖这种行为或其他什么呢?一种让代码更干净的方法是使用自定义绑定,通过使用元素的当前值初始化值绑定来包装值绑定
您甚至可以让它在您的视图模型上创建观察对象,如果它们不存在的话
绑定可能类似于:
ko.bindingHandlers.valueWithInit = {
init: function(element, valueAccessor, allBindingsAccessor, data) {
var property = valueAccessor(),
value = element.value;
//create the observable, if it doesn't exist
if (!ko.isWriteableObservable(data[property])) {
data[property] = ko.observable();
}
data[property](value);
ko.applyBindingsToNode(element, { value: data[property] });
}
};
你会像这样使用它:
<input value="someValue" data-bind="valueWithInit: 'firstName'" />
请注意,属性名在引号中,这允许绑定创建它,如果它不存在,而不是从未定义的值中出错
这是一个示例:这里有点晚了。实际上,我对RP的回答并不满意,因为它打破了敲除的声明性质。具体来说,如果使用valueWithInit定义属性,则不能在早期绑定中使用它。这是一个例子 您以同样的方式使用它,但它仍然是文档范围内的声明性文件:
<input data-bind="valueWithInit: firstName" value="Joe" />
注意valueWithInit
只是在引擎盖下使用initValue
查看它。如果自定义绑定太重,那么一个简单的解决方案是从DOM初始化可观察对象 例如,给定以下HTML表单:
<form name="person">
<input type="text" name="firstName" value="Joe" data-bind="value: firstName"/>
</form>
您可以简单地使用a并将值分配给现有的可观察对象:
ko.bindingHandlers.yourBindingName = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
viewModel.dataSource($(".dataSource").val());
viewModel.pageSize($(".pageSize").val());
}
};
然后,只需向输入中添加一个类或Id,并向包含它们的HTML元素中添加
data bind=“yourBindingName”
。可以使用的另一种方法是使用自定义绑定,通过使用元素的当前值初始化来包装值
绑定。您甚至可以让它在您的视图模型上创建可观察对象(如果不存在的话)。这是一个例子:嗯。。。现在我得到了在发出的HTML标记中显示的值,但是观察值仍然没有定义。你能在JSFIDLE中放一些东西吗?不管怎样,我已经让它工作了。这是个愚蠢的错误(和往常一样!)。你能把你的答案贴出来吗?这样我就可以接受你的答案了?感谢您的帮助,非常感谢:)事实上,如果属性名称不在引号中,它将不起作用。是的,此版本的绑定将要求名称在引号中。如果您知道您的可观察对象已经存在,那么您可以直接与它们绑定,只需在init
函数中根据元素的值设置可观察对象的值。我在过去使用过这个,我想补充一点,通过更改行ko.applybindingstode(元素,{value:data[property]});
到ko.applybindingstoode(元素,{textInput:data[property]});
获取实时双向更新。警告:initValue绑定必须在值(或任何其他值更改)绑定之前值得一提的是isModified()将设置为true,因此如果您不希望发生这种情况,则需要在设置值后将其设置为false。例如“valueAccessor().isModified(false)”
<form name="person">
<input type="text" name="firstName" value="Joe" data-bind="value: firstName"/>
</form>
ko.applyBindings({
firstName: ko.observable(document.forms['person']['firstName'].value)
});
ko.bindingHandlers.yourBindingName = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
viewModel.dataSource($(".dataSource").val());
viewModel.pageSize($(".pageSize").val());
}
};