2013-02-27 6 views
17

Ich beginne gerade mit AngularJS herumzuspielen und versuche die Bindungstechnik zu verstehen. Für den Anfang habe ich versucht, einen einfachen Umwandlungsrechner (Dutzende in Stücke, Stücke zu Dutzende) zu machen. Das funktionierte gut, aber als ich versuchte, sowohl einen Bereich Eingang und einen Nummer Eingang zur gleichen Modell Eigenschaft zu binden, der Nummer Eingang nicht aktualisiert, wenn der Bereich Wert eingestellt wird. Ich habe eine jsfiddle zeigt das Verhalten:Zwei-Wege-Bindung mit Bereichs- und Zahleneingabe in AngularJS

gemeinsamen JavaScript gebrochen und Arbeits Geigeen:

var myApp = angular.module('myApp', []); 

myApp.controller('CalcCtrl', function ($scope) { 
    var num = 0.0; 
    $scope.qty = new Quantity(12); 
    $scope.num = num; 
}); 

function Quantity(numOfPcs) { 
    var qty = numOfPcs; 
    var dozens = numOfPcs/12; 

    this.__defineGetter__("qty", function() { 
     return qty; 
    }); 

    this.__defineSetter__("qty", function (val) { 
     qty = val; 
     dozens = val/12; 
    }); 

    this.__defineGetter__("dozens", function() { 
     return dozens; 
    }); 

    this.__defineSetter__("dozens", function (val) { 
     dozens = val; 
     qty = val * 12; 
    }); 
} 

BROKEN FIDDLE

html:

<div ng-controller="CalcCtrl"> 
    <form> 
     <label for="pcs">Pieces:</label> 
     <input type="number" min="0" ng-model="qty.qty" size="20" id="pcs" 
     /> 
     <input type="range" min="0" max="100" ng-model="qty.qty" /> 
     <br/> 
     <label for="numOfDozens">Dozens</label> 
     <input type="number" min="0" ng-model="qty.dozens" size="20" 
     id="numOfDozens" /> 
    </form> 
</div> 

jedoch die Bindung zwei Anzahl Eingaben die gleiche Modelleigenschaft scheint gut zu funktionieren, wie in dieser Geige gezeigt:

WORKING FIDDLE

html:

<div ng-controller="CalcCtrl"> 
    <form> 
     <label for="pcs">Pieces:</label> 
     <input type="number" min="0" ng-model="qty.qty" size="20" id="pcs" 
     /> 
     <input type="number" min="0" max="100" ng-model="qty.qty" /> 
     <br/> 
     <label for="numOfDozens">Dozens</label> 
     <input type="number" min="0" ng-model="qty.dozens" size="20" 
     id="numOfDozens" /> 
    </form> 
</div> 

Irgendwelche Ideen, wie man einen Bereich und Anzahl Eingang in AngularJS zu einer einzigen Modell Eigenschaft gebunden zu bekommen? Vielen Dank.

+0

Ich glaube nicht type = "Bereich" unterstützt wird: https://github.com/angular/angular.js/issues/1189 Sie müssten wahrscheinlich Ihre eigene Direktive dafür schreiben. –

Antwort

17

Das Problem hierbei ist, dass die input type = "Bereich" arbeitet mit Strings und nicht mit Zahlen (während input type = "number" funktioniert nur mit Zahlen).

http://www.w3.org/wiki/HTML/Elements/input/range

Der Bereichszustand stellt eine Steuerung für den Wert des Elements Einstellung auf eine Anzahl eine Zeichenfolge repräsentiert.

Wenn Sie val = parseInt(val) als erste Anweisung auf dem qty Setter hinzufügen sollte es funktionieren:

this.__defineSetter__("qty", function (val) {   
    val = parseInt(val); 
    qty = val; 
    dozens = val/12; 
}); 

jsfiddle: http://jsfiddle.net/bmleite/2Pk3M/2/

+14

Ist kein Bereichseingang im Grunde eine Nummer auswählen? Warum benutzen sie Zeichenfolgen? –

+6

Es sollte 'parseInt (val, 10);' –

+1

@LiviuT sein. Sie verwendeten wahrscheinlich eine Zeichenfolge, um abwärtskompatibel zu sein. Bei älteren Browsern, die 'type =" range "nicht implementieren, ist die" Eingabe "weiterhin als Textfeld mit einem string-type" value "verwendbar. Wenn "Wert" in neueren Browsern immer noch eine Zeichenfolge ist, werden Browserkompatibilitätsfehler vermieden. –

7

Ich denke, diese Lösung mehr generisch ist.

myApp.directive('input', function() { 
return { 
    restrict: 'E', 
    require: '?ngModel', 
    link: function(scope, element, attrs, ngModel) { 
     if ('type' in attrs && attrs.type.toLowerCase() === 'range') { 
      ngModel.$parsers.push(parseFloat); 
     } 
    } 
}; 

});

full explanation

+0

Ich mag diese Lösung. Obwohl ich "parseFloat" durch "Number" ersetzt habe ;-) – joeytwiddle

0

Sie können es ng-model-options mit lösen.Ich änderte jsfiddle und hier ist der Code:

html:

<div ng-controller="CalcCtrl"> 
    <form> 
     <label for="pcs">Pieces:</label> 
     <input type="number" min="0" ng-model="qty.qty" size="20" id="pcs" ng-model-options="{ getterSetter: true }"/> 
     <input type="range" min="0" max="100" ng-model="qty.qty" ng-model-options="{ getterSetter: true }"/> 
     <br/> 
     <label for="numOfDozens">Dozens</label> 
     <input type="number" min="0" ng-model="qty.dozens" size="20" 
     id="numOfDozens" ng-model-options="{ getterSetter: true }"/> 
    </form> 
</div> 

js:

var myApp = angular.module('myApp', []); 

myApp.controller('CalcCtrl', function ($scope) { 
    var num = 1.0; 
    $scope.qty = { 
    qty:function (val) { 
     return arguments.length ? (num = parseFloat(val)) : num; 
    }, 
    dozens: function (val) { 
      return arguments.length ? (num = val*12) : num/12; 
     } 
    }; 
}); 
Verwandte Themen