[英]Knockout Custom Binding To An Object
I'm currently designing a in-browser calculator, and the functionality I want is to create an input box, and bind it to a object in the view-model. 我目前正在设计一个浏览器内计算器,我想要的功能是创建一个输入框,并将其绑定到视图模型中的对象。
This object will have a property called value, which will be what the input box displays, but I also want it to have min and max limits which which change the background colour of the box to red if they are exceeded. 此对象将具有一个名为value的属性,该属性将是输入框显示的属性,但我还希望它具有最小和最大限制,如果超过这些限制,则会将框的背景颜色更改为红色。
I got the basic input binding to work, but I'm having trouble creating my own custom binding wrapper for the input binding that also changes the background colour. 我得到了基本的输入绑定工作,但我无法为输入绑定创建自己的自定义绑定包装,也会改变背景颜色。
My HTML: 我的HTML:
<td><input data-bind="calcVar: resistance" type="text" size="16" /></td>
My Javascript: 我的Javascript:
The "class" to hold all the data 保存所有数据的“类”
var calcVar = function(value, lowerBound, upperBound) {
this.value = ko.observable(value);
this.lowerBound = ko.observable(lowerBound);
this.upperBound = ko.observable(upperBound);
};
Creating a variable in the view-model: 在视图模型中创建变量:
this.fSwAct = ko.observable(new calcVar(200, 100, 100, 0, 1000));
Start-up function 启动功能
// Start-up function
j(document).ready(
function StartUp()
{
// Create custom binding
ko.bindingHandlers.calcVar = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
ko.bindingHandlers.value.init(element, valueAccessor()().value, allBindings, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Call value binding (child binding)
ko.bindingHandlers.value.update(element, valueAccessor()().value, allBindings, viewModel, bindingContext);
}
};
// Activates knockout.js
var app = new AppViewModel();
ko.applyBindings(app);
}
);
Although the custom binding function is being called, the input bindings don't seem to work, and other calculated fields don't update when the value is changed. 虽然正在调用自定义绑定函数,但输入绑定似乎不起作用,并且在更改值时其他计算字段不会更新。 I feel it's something to do with the way I am creating the calcVar "class" or passing it it in to the input binding. 我觉得这与我创建calcVar“类”或将其传递给输入绑定的方式有关。
You don't actually need a custom binding to do make the background red, you can just use the style builtin binding. 你实际上并不需要自定义绑定来使背景变红,你可以只使用样式内置绑定。 But making a custom binding does result in a cleaner markup. 但是,进行自定义绑定会产生更清晰的标记。 Here are two example implementations, one with custom bindings, one without (fiddle: http://jsfiddle.net/EWdmV/5/ ): 这里有两个示例实现,一个是自定义绑定,一个没有(小提琴: http : //jsfiddle.net/EWdmV/5/ ):
html: HTML:
<span>--------- no custom binding ---------</span><br />
<td><input data-bind="value:value, valueUpdate:'afterkeydown', style:{ 'background-color' : isOutsideBounds() ? 'red':'white'}" type="text" size="16" /></td>
<span>--------- with custom binding ---------</span><br />
<td><input data-bind="value:value, valueUpdate:'afterkeydown', calcVar: isOutsideBounds" type="text" size="16" /></td>
js: JS:
var CalcVar = function(value, lowerBound, upperBound) {
var self = this;
self.value = ko.observable(value);
self.lowerBound = ko.observable(lowerBound);
self.upperBound = ko.observable(upperBound);
self.isOutsideBounds = ko.computed(function(){
var val = parseFloat(self.value(),10);
console.log(val);
console.log(val > self.upperBound() || val < self.lowerBound());
return val > self.upperBound() || val < self.lowerBound();
}, self);
};
ko.bindingHandlers.calcVar = {
init:function(element, valueAccessor){
},
update:function(element, valueAccessor){
if(valueAccessor()()){
$(element).css("backgroundColor", "red");
} else {
$(element).css("backgroundColor", "white");
}
}
}
ko.applyBindings(new CalcVar(100, 10,1000));
EDIT: If you really want shorter markup, here are another two alternatives, using a template, and using a custom binding which calls renderTemplate (probably this is what you need) (updated fiddle: http://jsfiddle.net/EWdmV/14/ ): 编辑:如果你真的想要更短的标记,这里有另外两个选择,使用模板,并使用调用renderTemplate的自定义绑定(可能这是你需要的)(更新的小提琴: http : //jsfiddle.net/EWdmV/14 / ):
html: HTML:
<span>--------- with custom binding tempalate ---------</span><br />
<div data-bind="template:{name:'superCalcTemplate', data:resistor1}" ></div>
<br />
<span>--------- with super custom binding ---------</span><br />
<div data-bind="superCalcVar:resistor1"></div>
<div data-bind="superCalcVar:resistor2"></div>
<script type="text/html" id="superCalcTemplate">
<input data-bind="value:value, valueUpdate:'afterkeydown', calcVar: isOutsideBounds" type="text" size="16" />
</script>
js: JS:
ko.bindingHandlers.calcVar = {
init:function(element, valueAccessor, allBindings, viewModel, bindingContext){
},
update:function(element, valueAccessor, allBindings, viewModel, bindingContext){
if(valueAccessor()()){
$(element).css("backgroundColor", "red");
} else {
$(element).css("backgroundColor", "white");
}
}
}
ko.bindingHandlers.superCalcVar = {
init:function(element, valueAccessor, allBindings, viewModel, bindingContext){
ko.renderTemplate("superCalcTemplate", valueAccessor(), {}, element, "replaceChildren");
return { controlsDescendantBindings: true };
},
update:function(element, valueAccessor, allBindings, viewModel, bindingContext){
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.