2013-02-27 7 views
17

Sto appena iniziando a giocare con AngularJS e sto cercando di capire la tecnica di rilegatura. Per cominciare, ho provato a fare un semplice calcolatore di conversione (dozzine di pezzi, pezzi a dozzine). Che funzionava bene, ma quando ho cercato di legare sia gamma ingresso ed un ingresso numero alla stessa proprietà modello il numero ingresso non aggiorna quando il valoregamma viene regolata. Ho una jsfiddle che mostra il comportamento:Associazione a due vie con intervallo e immissione di numeri in AngularJS

JavaScript comune per fiddles lavoro rotti e:

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> 

Tuttavia, vincolante due numero ingressi la stessa proprietà del modello sembra funzionare bene come mostrato in questo violino:

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> 

Delle idee come ottenere una gamma e numero ingresso legato a una singola proprietà modello AngularJS? Grazie.

+0

Non credo type = "range" è supportato: https://github.com/angular/angular.js/issues/1189 Probabilmente dovresti scrivere la tua direttiva per questo. –

risposta

17

Il problema è che il tipo di ingresso = "range" lavora con Corde e non con numeri (mentre input type = "numero" funziona solo con i numeri).

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

Lo stato gamma rappresenta un comando per impostare il valore dell'elemento di una stringa che rappresenta un numero.

Se si aggiunge val = parseInt(val) come prima istruzione sulla qty setter dovrebbe funzionare:

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

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

+14

Non è un ingresso di gamma fondamentalmente un numero selezionato? Perché stanno usando le stringhe? –

+6

Dovrebbe essere 'parseInt (val, 10);' –

+1

@LiviuT. Probabilmente hanno usato una stringa per essere retrocompatibile. Sui browser più vecchi che non implementano 'type =" range "', l'input 'sarà ancora utilizzabile come campo di testo, con un' valore' di tipo stringa. Rendere "valore" ancora una stringa nei browser più recenti evita i bug di compatibilità del browser. –

7

Penso che questa soluzione è più generico.

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

Mi piace questa soluzione. Anche se ho sostituito 'parseFloat' con' Number' ;-) – joeytwiddle

0

È possibile risolverlo usando ng-model-options.Ho cambiato jsfiddle e qui è il codice:

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; 
     } 
    }; 
}); 
Problemi correlati