5

AngularJS: ng-model setter dentro ng-repeat

Ho trovato delle ottime risposte su come ottenere il valore di un ng-model all'interno di uno ng-repeat, ma finora non ho trovato nessuna che riguardi il setter. Supponiamo che io sono qualcosa di simile:

<div ng-repeat="item in getItems()"> 
    <input ng-model="itemTitle" ng-model-options={getterSetter:true}"> 
</div> 

Se avessi una singola casella di input, mi piacerebbe usare qualcosa come this:

... 
var _val = ''; 
$scope.itemTitle = function(val){ 
    return angular.isDefined(val) ? (_val = val) : _val; 
} 
... 

tuttavia, che avrebbe cambiato il valore di ogni singola casella di input. È possibile definire le variabili e un setter, potenzialmente utilizzando gli array? O c'è un metodo migliore per ottenere e impostare caselle di input all'interno di una ng-repeat?

risposta

2

Impostare ng-model su item.title in modo che ogni oggetto nell'array restituito da getItems() contenga un title.

<div ng-repeat="item in getItems()"> 
    <input type="text" ng-model="item.title"/> 
</div> 
+0

Come creo il setter? Così com'è, tutto ciò che hai fatto è stato rinominato come variabile. L'acquisizione non è il problema; è l'impostazione. –

+0

Non l'hai menzionato nella tua domanda quindi l'ho lasciato così com'è. Cosa stai cercando di ottenere con 'ng-model-options = {getterSetter: true}' –

+0

Ho un elenco dinamico di elementi, ognuno con una casella di input. Mi piacerebbe sia ottenere i dati da ogni singola casella e impostarlo. –

5

Il answer da Wayne Ellery fa rispondere alla domanda mostra "un metodo migliore per ottenere e impostare caselle di input all'interno di un ng-repeat".

Tuttavia, se si vuole realmente utilizzare ng-model-options="{getterSetter: true}" all'interno di un ng-repeat come è implicito nella domanda e le osservazioni quindi è un po 'più complicata in quanto all'interno della vostra funzione getterSetter non si sa quale elemento dal ng-repeat viene indicato.

In sostanza, ciò che devi fare è passare una funzione getter/setter diversa per ogni elemento, e puoi farlo passando una funzione a ng-model che crea il tuo getter/setter specifico per le righe.

<div ng-app="app" ng-controller="ctrl"> 
    <div ng-repeat='row in items'> 
    <span>{{row.name}}</span> 
    <input type='text' ng-model='createTitleGetterSetter(row.name)' 
     ng-model-options='{ getterSetter: true }' /> 
    </div> 
    <hr/> 
    <pre>{{ itemTitles | json }}</pre> 
</div> 

E il codice JS:

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

app.controller('ctrl', function($scope) { 
    $scope.items = [ 
     {'name': 'a'}, 
     {'name': 'b'}, 
     {'name': 'c'} 
    ]; 

    $scope.itemTitles = {}; 
    $scope.createTitleGetterSetter = function(name) { 
     if (!$scope.itemTitles[name]) { 
      $scope.itemTitles[name] = { 
       getterSetter: function(newValue) { 
         return arguments.length === 0 ? 
         $scope.itemTitles[name].title : 
         $scope.itemTitles[name].title = newValue; 
       }, 
       title: '' 
      } 
     } 

     return $scope.itemTitles[name].getterSetter; 
    }; 
}); 

JSFiddle qui: non http://jsfiddle.net/zLg3mLd0/1/

In questo caso i titoli delle voci sono ovviamente memorizzati con gli oggetti voce (se si voleva farlo , basta un semplice ng-model) ma nella mappa itemTitles.

Credito a this answer e ai suoi commenti su cui questa risposta è fortemente basata.