【问题标题】:Knockout Custom Binding To An Object淘汰自定义绑定到对象
【发布时间】:2013-11-04 01:09:44
【问题描述】:

我目前正在设计一个浏览器内计算器,我想要的功能是创建一个输入框,并将其绑定到视图模型中的一个对象。

这个对象将有一个名为 value 的属性,这将是输入框显示的内容,但我还希望它具有最小和最大限制,如果超出它们会将框的背景颜色更改为红色。

我得到了基本的输入绑定,但我在为输入绑定创建自己的自定义绑定包装器时遇到了麻烦,该包装器也会改变背景颜色。

我的 HTML:

<td><input data-bind="calcVar: resistance" type="text" size="16" /></td>

我的 Javascript:

保存所有数据的“类”

var calcVar = function(value, lowerBound, upperBound) {
        this.value = ko.observable(value);
        this.lowerBound = ko.observable(lowerBound);
        this.upperBound = ko.observable(upperBound);
};

在视图模型中创建一个变量:

this.fSwAct = ko.observable(new calcVar(200, 100, 100, 0, 1000));

启动功能

// 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);  
    }
);

虽然正在调用自定义绑定函数,但输入绑定似乎不起作用,并且当值更改时,其他计算字段不会更新。我觉得这与我创建 calcVar“类”或将其传递给输入绑定的方式有关。

【问题讨论】:

    标签: javascript binding knockout.js


    【解决方案1】:

    您实际上不需要自定义绑定来使背景变红,您可以使用内置的样式绑定。但是进行自定义绑定确实会产生更清晰的标记。这里有两个示例实现,一个有自定义绑定,一个没有(fiddle:http://jsfiddle.net/EWdmV/5/):

    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:

    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));
    

    编辑:如果你真的想要更短的标记,这里有另外两种选择,使用模板,并使用调用 renderTemplate 的自定义绑定(可能这就是你需要的)(更新小提琴:http://jsfiddle.net/EWdmV/14/):

    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:

    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){                               
        }
    }
    

    【讨论】:

    • 谢谢,这肯定有帮助!但我所追求的是能够通过标记中的一个绑定添加值和背景突出显示,例如&lt;input data-bind="calcVar:resistor1"/&gt; 这是因为我打算在输入框中添加更多的绑定功能,并且有很多,所以只需一个绑定操作就值得了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多