4 votes

Comment accéder à $viewValue depuis le contrôleur en Angular

J'ai une application angulaire configurée comme suit. Ng-repeat contenant des éléments li avec 2 entrées chacun (enfin plus que 2 mais pour cette démo j'en ai 2) .

La directive définit le contrôleur.

HTML

<li ng-repeat="lw in lw_list"   my-lw   ng-model="lw"  >            
    <input my-cell ng-init="init(lane , $index , 'name')"  ng-class="'lib_name inline_div'" type='text'     value="{{ lw.library.name }}" >
    <input my-cell ng-init="init(lane , $index , 'volume')  "ng-class="'number_field'"      type="number"   ng-model='volume' />    
</li>                       

javascript

angular.module('Demo').directive("myCell",  function(CellStore){
    return {
            controller : 'CellCtrl' , 
        };
}) ;

angular.module('Demo').controller('CellCtrl' , function($scope , CellStore){
    $scope.init = function(lane, row, column){
        $scope.row = row  ;
        $scope.column = column ; 
        console.log("init" ,  $scope.$parent );
        CellStore.addCell(  lane.lane,  row, column , $viewValue ) ; 
    } ; 
}) ; 

L'idée est donc que lorsque chaque entrée est créée, elle appelle la fonction init, qui stocke la valeur de l'entrée dans un hash imbriqué (pour la récupérer plus tard). Cependant, je ne sais pas comment accéder à la variable $viewValue (la valeur que les entrées contiennent) à partir du contrôleur.

11voto

XMLilley Points 2351

D'autres ont résolu votre problème, mais je ne vois pas de réponse à votre question principale, qui est de savoir comment accéder à $viewValue depuis le contrôleur, si vous vouliez le faire.

Ce que vous faites réellement, c'est accéder à l'instance de ngModelController qui est attaché à chaque entrée. Si vous mettez simplement un name sur votre élément de formulaire et sur chaque entrée qu'il contient, leurs contrôleurs seront alors accessibles sur l'onglet $scope . (Puisque vous utilisez un ng-repeat, il vous faudrait une sorte de système de dénomination dynamique pour pouvoir les atteindre tous. Vous pouvez aussi simplement les itérer).

Une fois que vous avez tout nommé, pour obtenir l'instance, c'est simple :

var instance = $scope.formName.inputName;

Et $viewValue devrait être à :

instance.$viewValue

Une fois que vous avez obtenu cette référence, vous pouvez également utiliser les autres méthodes de ngModelController, par exemple

instance.$setValidity();

EDIT : Vous pouvez jouer avec cela, et voir comment cela se rapporte à certains problèmes de validation, sur le site suivant ce Codepen .

2voto

jonnyynnoj Points 2670

Comme le dit @BoxerBucks, refactorez votre code en un link et faire le lien à partir de là. Vous pouvez également vous passer de la fonction ng-init car la fonction de liaison est appelée lors de la création de la directive.

Tout d'abord, j'ai légèrement modifié la directive pour qu'elle prenne le nom de la colonne dans la valeur d'attribut de my-cell (le lw et l'objet $index sont tous les deux sur la portée, il n'y a donc pas besoin de les passer) :

<li ng-repeat="lw in lw_list" >            
    <input my-cell="name" ng-class="'lib_name inline_div'" type='text' ng-model="lw.name" >
    <input my-cell="volume" ng-class="'number_field'" ng-model='lw.volume' />    
</li>

Ensuite, la fonction de liaison l'enregistre avec CellStore :

app.directive("myCell",  function(CellStore){
    return function(scope, elem, attrs) {
        CellStore.addCell(scope.lw, scope.$index, attrs.myCell);
    };
});

Et enfin, le addCell méthode :

app.service('CellStore', function() {
    this.addCell = function(lw, row, column) {
        console.log('add cell:', lw.name, row, column, lw[column]);
    };
});

http://jsfiddle.net/9Lmwj/2/

Je n'étais pas vraiment sûr de la structure de vos données, mais j'espère que c'est un début utile.

0voto

BoxerBucks Points 1697

Vous pouvez placer le code d'initialisation dans la directive et passer les données dont vous avez besoin :

<input my-cell  ng-class="'lib_name inline_div'" type='text' value="{{ lw.library.name }}" >

Ensuite, la directive se transforme en quelque chose comme ceci :

angular.module('Demo').directive("myCell",  function(){
    return {
            function(scope, element, attrs){}
                 scope.row = row;
                 scope.column = column; 
                 scope.CellStore.addCell(scope.lane.lane, row, column, attrs.value); 
        };
}) ;

Comme je ne peux pas voir le reste du code de votre application, il se peut que vous deviez changer certains noms de variables pour que cela fonctionne, mais le principe de base est d'utiliser la fonction link de la directive pour exécuter votre initialisation. De plus, dans la directive, vous avez accès à la portée héritée où votre directive est déclarée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X