从HTML标记中为observable赋予初始值
Giving initial value to observable from the HTML markup
我正在尝试创建一个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" />
但是,当页面呈现时,当我检查元素时,我注意到输入字段的value
被设置为一个空字符串,我认为这是因为声明可观察性的方式。但是,有没有一种方法可以推翻这种行为或其他什么?
这里有点晚了。事实上,我对RP的回答并不满意,因为它打破了Knockout的声明性。特别是,如果使用valueWithInit定义属性,则不能在早期绑定中使用。这是他的一把叉子。
您以相同的方式使用它,但它仍然是文档范围内的声明性文件:
<input data-bind="valueWithInit: firstName" value="Joe" />
扩展这个想法,您还可以使用它来分离初始化和绑定:
<input data-bind="initValue: lastName, value: lastName" value="Smith" />
这有点多余,但当您使用插件而不是内置绑定时会变得有用:
<input data-bind="initValue: lastName, myPlugin: lastName" value="Smith" />
再扩展一点,我还需要一种初始化复选框的方法:
<input type="checkbox" data-bind="checkedWithInit: isEmployed" checked />
下面是处理程序:
ko.bindingHandlers.initValue = {
init: function(element, valueAccessor) {
var value = valueAccessor();
if (!ko.isWriteableObservable(value)) {
throw new Error('Knockout "initValue" binding expects an observable.');
}
value(element.value);
}
};
ko.bindingHandlers.initChecked = {
init: function(element, valueAccessor) {
var value = valueAccessor();
if (!ko.isWriteableObservable(value)) {
throw new Error('Knockout "initChecked" binding expects an observable.');
}
value(element.checked);
}
};
ko.bindingHandlers.valueWithInit = {
init: function(element, valueAccessor, allBindings, data, context) {
ko.applyBindingsToNode(element, { initValue: valueAccessor() }, context);
ko.applyBindingsToNode(element, { value: valueAccessor() }, context);
}
};
ko.bindingHandlers.checkedWithInit = {
init: function(element, valueAccessor, allBindings, data, context) {
ko.applyBindingsToNode(element, { initChecked: valueAccessor() }, context);
ko.applyBindingsToNode(element, { checked: valueAccessor() }, context);
}
};
请注意,valueWithInit
只是在后台使用initValue
。
在jsfiddle上看到它的作用。
您可以使用一个自定义绑定来保持代码的整洁,该绑定通过使用元素的当前值初始化值绑定来封装值绑定。
您甚至可以让它在您的视图模型上创建可观察对象,如果它们不存在的话。
绑定可能看起来像:
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'" />
请注意,属性名称是用引号括起来的,这允许绑定在不存在的情况下创建它,而不是从未定义的值中出错。
以下是一个示例:http://jsfiddle.net/rniemeyer/BnDh6
如果自定义绑定太重,那么一个简单的解决方案是从DOM初始化可观察对象。
例如,给定以下HTML表单:
<form name="person">
<input type="text" name="firstName" value="Joe" data-bind="value: firstName"/>
</form>
然后Knockout可以初始化如下:
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());
}
};
然后,只需向输入添加一个类或Id,并向包含它们的HTML元素添加data-bind="yourBindingName"
。
- 可以't让我的if语句处理js中的html表单输入
- 如何设置html元素填充的动画
- 使用JS如何动态更改显示的html文件中的文本背景颜色
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 如何编写HTML输入的JS内联
- Dojo不解析自定义小部件的模板html中的小部件声明性
- 使用javascript将动态表从一个html页面打印到另一个html页
- 通过javascript重定向html传递php变量
- 如何使Javascript动态html表及其上的事件
- 在chrome.tabs.onCreated之后加载HTML页面
- 如何在vs2002中调试html页面
- 如何使用javascript或html下载PDF格式的填写表单
- 视频HTML没有'无法在Internet Explorer 11上工作
- HTML表单提交时未执行外部函数
- 如何将输入(type=text)从html表单传递到javascript函数
- 使用angular重定向到html页面
- 从HTML标记中为observable赋予初始值
- Knockout.js:更改Observable的值不会更改html中attribute的值
- knocket js阻止现有的html observable进行更新
- 如何将knockout's的Observable数组长度绑定到一个html元素