web-dev-qa-db-fra.com

Utilisation de ControllerAs avec une directive

J'essaie de suivre le guide de style angularJS de John Papa ici et j'ai commencé à changer mes directives pour utiliser controllerAs. Cependant, cela ne fonctionne pas. Mon modèle ne semble pas accéder à tout ce qui est attribué à VM. Voir cet exemple plnkr très simple qui présente le comportement.

http://plnkr.co/edit/bVl1TcxlZLZ7oPCbk8sk?p=preview

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

angular
    .module('app')
    .directive('test', test);

function test() {
    return {
        restrict: 'E',
        template: '<button ng-click="click">{{text}}</button>',
        controller: testCtrl,
        controllerAs: 'vm'
    }
}

angular
    .module('app')
    .controller('testCtrl', testCtrl);

function testCtrl() {
  var vm = this;
  vm.text = "TEST";
}
26
Ryan Langton

Lorsque vous utilisez la syntaxe controllerAs, vous n'accédez pas à la portée $ comme vous le feriez normalement, la variable vm est ajoutée à la portée, donc votre bouton doit devenir:

<button ng-click="click">{{vm.text}}</button>

Remarquez le vm. ajouté au début de text.

Voici un fork de votre Plunk avec le correctif appliqué


Q: Savez-vous comment j'accéderais aux attributs transmis en tant qu'attributs à la directive, exemple "scope: {text: '@'}"? Suis-je alors obligé d'utiliser $ scope sur le contrôleur et de définir vm.text = $ scope.text?

R: Dans l'article que vous référencez, il y a ne section y075 qui ne parle que de ce scénario. Regardez dans bindToController:

return {
    restrict: 'E',
    template: '<button ng-click="click">{{text}}</button>',
    controller: testCtrl,
    controllerAs: 'vm',
    scope: {
        text: '@'
    },
    bindToController: true // because the scope is isolated
};

Vous devriez alors pouvoir accéder à vm.text

37
Tr1stan

Avec "controllerAs", l'alias d'instance de contrôleur - vm, dans votre cas - est publié sur la portée en tant que .vm propriété de l'étendue.

Donc, pour accéder à ses propriétés (c'est-à-dire les propriétés du contrôleur), vous devez spécifier {{vm.text}} ou ng-click="vm.click".

4
New Dev

Lorsque vous utilisez la syntaxe 'controllerAs', comme ci-dessus, la portée est liée à la référence 'this' du contrôleur. Cela nous permet donc d'introduire un nouvel espace de noms ('vm' ici) lié à notre contrôleur sans avoir besoin de mettre les propriétés de portée dans un objet littéral supplémentaire (disons $ scope) . Donc, accéder à tout ce qui est dans la portée du contrôleur, nécessite 'vm' namespace, as,

'<button ng-click="click">{{vm.text}}</button>'
1
Amardeep Kohli

Lorsque vous utilisez la syntaxe controllerAs, vous devez utiliser

bindToController: true

cela fonctionnera dans votre directive.

1
jitendra varshney