0

私は現在、ブラウザー内の電卓を設計しています。必要な機能は、入力ボックスを作成し、それをビューモデルのオブジェクトにバインドすることです。

このオブジェクトには 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「クラス」を作成する方法、またはそれを入力バインディングに渡す方法に関係があると感じています。

4

1 に答える 1

2

背景を赤くするためにカスタムバインディングは実際には必要ありません。スタイルの組み込みバインディングを使用できます。ただし、カスタム バインディングを作成すると、マークアップがよりクリーンになります。以下に 2 つの実装例を示します。1 つはカスタム バインディングを使用し、もう 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 を呼び出すカスタム バインディングを使用する方法の 2 つがあります (おそらくこれが必要です) (フィドルの更新: 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){                               
    }
}
于 2013-11-04T03:08:29.163 に答える