2013-01-06 2 views
76

J'essaie de générer un ensemble de cases à cocher à partir d'un tableau d'objets. Je souhaite que les cases à cocher mappent dynamiquement leur modèle ng à une propriété du nouvel objet qui sera soumis dans le tableau.Affectation dynamique ng-model

Ce que j'avais à l'esprit est quelque chose comme

<li ng-repeat="item in items"> 
    <label>{{item.name}}</label> 
    <input type="checkbox" ng-model="newObject.{{item.name}}"> 
</li> 

Cela ne fonctionne pas comme on le voit sur cette jsFiddle:

http://jsfiddle.net/GreenGeorge/NKjXB/2/

Quelqu'un peut-il aider?

Répondre

140

Cela devrait vous donner les résultats souhaités:

<input type="checkbox" ng-model="newObject[item.name]"> 

Voici un Plunk de travail: http://plnkr.co/edit/ALHQtkjiUDzZVtTfLIOR?p=preview

+1

hmm fait cela m'a donné littéralement '', est-il quelque chose im manquant? –

+0

Hmm, étrange, juste ajouté un exemple en direct (plunker depuis pour une raison quelconque jsFiddle ne fonctionne pas de mon côté aujourd'hui). –

+0

ah oui, j'avais l'habitude de penser en php et je m'attendais à ce que le balisage actuel change pour le nom, ça a marché. THX! –

23

EDIT Comme noté à juste titre dans les commentaires avec ce réglage ng changement nécessite une « factice » ng-model doit être présent à l'avance. Il convient toutefois de noter qu'apparemment avec 1.3 les options requises ont été fournies par le cadre. S'il vous plaît vérifier https://stackoverflow.com/a/28365515/3497830 ci-dessous! /EDIT

Juste au cas où vous êtes comme moi trébucher sur un cas simple, tout en ayant une tâche plus complexe, c'est la solution que je suis venu avec pour lier dynamiquement des expressions arbitraires à ng-modèle: http://plnkr.co/edit/ccdJTm0zBnqjntEQfAfx?p=preview

Méthode: J'ai créé une directive dynamicModel qui prend une expression angulaire standard, l'évalue et lie le résultat à la portée via ng-model et $ compile.

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

app.controller('MainCtrl', function($scope) { 
    $scope.data = {}; 
    $scope.testvalue = 'data.foo'; 
    $scope.eval = $scope.$eval; 
}); 

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

app.controller('MainCtrl', function($scope) { 
    $scope.data = {}; 
    $scope.testvalue = 'data.foo'; 
    $scope.eval = $scope.$eval; 
}); 

app.directive('dynamicModel', ['$compile', function ($compile) { 
    return { 
     'link': function(scope, element, attrs) { 
      scope.$watch(attrs.dynamicModel, function(dynamicModel) { 
       if (attrs.ngModel == dynamicModel || !dynamicModel) return; 

       element.attr('ng-model', dynamicModel); 
       if (dynamicModel == '') { 
        element.removeAttr('ng-model'); 
       } 

       // Unbind all previous event handlers, this is 
       // necessary to remove previously linked models. 
       element.unbind(); 
       $compile(element)(scope); 
      }); 
     } 
    }; 
}]); 

Utilisation dynamique est tout simplement modèle = « angularExpression » où les résultats de angularExpression dans une chaîne de caractères qui est utilisé comme modèle pour l'expression de ng.

J'espère que cela évite à quelqu'un d'avoir mal à la tête de devoir trouver cette solution.

Cordialement, Justus

+3

Vous êtes un sauveur J'ai presque désespéré avant de trouver ce poste –

+0

Cela ne fonctionne pas avec ng-change –

+0

Pouvez-vous être plus précis Brian? Qu'est-il arrivé? –

6

Avec angulaire 1.3, vous pouvez utiliser ng-model-options directive pour attribuer dynamiquement le modèle, ou se lier à une expression.

Voici un plunkr: http://plnkr.co/edit/65EBiySUc1iWCWG6Ov98?p=preview

<input type="text" ng-model="name"><br> 
<input type="text" ng-model="user.name" 
ng-model-options="{ getterSetter: true }"> 

Plus d'info sur ngModelOptions ici: https://docs.angularjs.org/api/ng/directive/ngModelOptions

+0

Pardonnez-moi si je manque quelque chose, mais rien de votre Le plunk semble inclure l'assignation de modèle dynamique. Et rien à propos de ngModelOptions ne supporte évidemment cela. Pourriez-vous peut-être clarifier? Parce que ce serait super-utile si cela fonctionnait, en fait, de cette façon ... – XML

+0

@XMLilley "getterSetter: valeur booléenne qui détermine si les fonctions liées à ngModel comme getters/setters sont traitées ou non." –

+0

Merci Rob d'avoir porté ceci à mon attention, j'ai mis à jour ma réponse et je l'ai liée à la vôtre. –

1

Ceci est mon approche pour soutenir l'expression plus profonde, par exemple 'Model.level1.level2.value'

<input class="form-control" ng-model="Utility.safePath(model, item.modelPath).value"> 

où item.modelPath = 'level1.level2' et utilitaire (modèle 'level1.level2') est la fonction d'utilité qui retourne model.level1.Niveau 2

+0

Pouvez-vous nous expliquer comment cela fonctionne? Que retourne Utility.safePath de sorte que vous puissiez ensuite utiliser .value? –

0

<!DOCTYPE html> 
 
<html> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> 
 
<body> 
 

 
    <div ng-app="myApp" ng-controller="myCtrl"> 
 
     <form name="priceForm" ng-submit="submitPriceForm()"> 
 
      <div ng-repeat="x in [].constructor(9) track by $index"> 
 
       <label> 
 
        Person {{$index+1}} <span class="warning-text">*</span> 
 
       </label> 
 
       <input type="number" class="form-control" name="person{{$index+1}}" ng-model="price['person'+($index+1)]" /> 
 

 
      </div> 
 
      <button>Save</button> 
 
     </form> 
 
    </div> 
 

 
    <script> 
 
     var app = angular.module('myApp', []); 
 
     app.controller('myCtrl', function ($scope) { 
 
      $scope.price = []; 
 
      $scope.submitPriceForm = function() { 
 
       //objects be like $scope.price=[{person1:value},{person2:value}....] 
 
       console.log($scope.price); 
 
      } 
 
     }); 
 
    </script> 
 
</body> 
 
</html>

Questions connexes