Syntaxe du «contrôleur en tant que» AngularJs - clarification?

121

J'ai lu la nouvelle syntaxe d'angularJS concernantcontroller as xxx

La syntaxe InvoiceController as invoiceindique à Angular d'instancier le contrôleur et de l'enregistrer dans la facture variable dans la portée actuelle.

Visualisation:

entrez la description de l'image ici

Ok, donc je n'aurai pas le paramètre $scopedans mon contrôleur et le code sera beaucoup plus propre dans le contrôleur.

Mais

Je devrai spécifier un autre alias dans la vue

Donc, jusqu'à présent, je pouvais faire:

<input type="number" ng-model="qty"  />

....controller('InvoiceController', function($scope) {
   // do something with $scope.qty <--notice

Et maintenant je peux faire:

 <input type="number" ng-model="invoic.qty"  /> <-- notice 

  ....controller('InvoiceController', function() {
       // do something with  this.qty  <--notice

Question

Quel est le but de le faire? supprimer d'un endroit et ajouter à un autre endroit?

Je serai heureux de voir ce qui me manque.

Royi Namir
la source
8
Cette vidéo l'explique très bien. youtube.com/watch?v=tTihyXaz4Bo Je pense qu'il est utilisé pour un code plus propre dans le HTML.
Fizer Khan
1
Clarté. Je ne suis pas dérangé d'utiliser $ scope.x Vs this.x dans le contrôleur, mais à mon avis, la liaison avec {{facture.x}} me dit plus que juste {{x}} (à mon humble avis). De plus, je me demande si cela résout un problème dont j'ai entendu parler dans angular où les non-objets dans le contrôleur ont des problèmes (donc things.x conviendrait, mais x causerait un problème).
Matt Roberts
1
@MattRoberts pour répondre à votre dernier commentaire - le problème non-objet que vous référencez n'est pas un problème angulaire autant qu'un fait d'héritage prototypique javascript. Il y a une bonne explication de la raison pour laquelle cela se produit en angulaire ici (avec pourquoi le controller ascorrige).
Russ Matney
Comment vais-je remplacer $ scope. $ Broadcast? dans ce nouveau cas parce que mon émission. $ ne semble pas fonctionner
Gaurav
1
@Gaurav, vous pouvez toujours injecter le service $ scope dans votre contrôleur, même si vous utilisez le contrôleur comme syntaxe pour certaines propriétés, méthodes, etc.
Derek

Réponses:

163

Il y a plusieurs choses à ce sujet.

Certaines personnes n'aiment pas la $scopesyntaxe (ne me demandez pas pourquoi). Ils disent qu'ils pourraient simplement utiliser this. C'était l'un des objectifs.

Il est également très utile d'indiquer clairement l'origine d'une propriété.

Vous pouvez imbriquer des contrôleurs et lors de la lecture du html, il est assez clair d'où vient chaque propriété.

Vous pouvez également éviter certains des problèmes de règle de point .

Par exemple, ayant deux contrôleurs, tous deux avec le même nom 'nom', vous pouvez faire ceci:

<body ng-controller="ParentCtrl">
    <input ng-model="name" /> {{name}}

    <div ng-controller="ChildCtrl">
        <input ng-model="name" /> {{name}} - {{$parent.name}}
    </div>
</body>

Vous pouvez modifier à la fois le parent et l'enfant, pas de problème à ce sujet. Mais vous devez utiliser $parentpour voir le nom du parent, car vous l'avez observé dans votre contrôleur enfant. En code html massif$parent peut être problématique, vous ne savez pas d'où vient ce nom.

Avec controller asvous pouvez faire:

<body ng-controller="ParentCtrl as parent">
    <input ng-model="parent.name" /> {{parent.name}}

    <div ng-controller="ChildCtrl as child">
      <input ng-model="child.name" /> {{child.name}} - {{parent.name}}
    </div>
</body>

Même exemple, mais il est beaucoup plus clair à lire.

Jésus Rodriguez
la source
10
Voici également un très bon exemple de la raison pour laquelle cette approche peut être déroutante pour certains: stackoverflow.com/questions/25405543/…
Julian Hollmann
Ceci est très utile lorsque vous imbriquez des contrôleurs!
C_J
1
J'ai des problèmes avec une implémentation similaire de votre réponse, veuillez consulter stackoverflow.com/questions/38315538
Cody
Cela vous permet également d'utiliser une classe es6 comme contrôleur et de référencer les méthodes dans le HTML. foo() { ... }est bien plus propre que $scope.foo = function() { ... }.
Brian McCutchon
17

Le principal avantage de la controller assyntaxe que je vois est que vous pouvez travailler avec des contrôleurs en tant que classes, pas seulement quelques fonctions de décoration $ scope, et tirer parti de l'héritage. Je rencontre souvent une situation où il y a une fonctionnalité qui est très similaire à un certain nombre de contrôleurs, et la chose la plus évidente à faire est de créer une BaseControllerclasse et d'en hériter.

Même s'il y a l'héritage $ scope, qui résout partiellement ce problème, certaines personnes préfèrent écrire du code d'une manière plus POO, ce qui, à mon avis, rend le code plus facile à raisonner et à tester.

Voici un violon à démontrer: http://jsfiddle.net/HB7LU/5796/

Roman Kolpak
la source
1
Cela devrait obtenir plus de votes positifs, car le violon est vraiment utile
Mawg dit de réintégrer Monica le
13

Je pense qu'un avantage particulier est clair lorsque vous avez des étendues imbriquées. Il sera maintenant complètement clair de quelle portée provient une référence de propriété.

David M. Karr
la source
7

La source

Différence entre la création d'un contrôleur à l'aide de $scope objectet l'utilisation de la “controller as”syntaxe et de vm

Création d'un contrôleur à l'aide de l'objet $ scope

Habituellement, nous créons un contrôleur en utilisant l'objet $ scope comme indiqué dans la liste ci-dessous:

myApp.controller("AddController", function ($scope) {



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

        $scope.result = $scope.number1 + $scope.number2;

    }

});

Ci-dessus, nous créons l'AddController avec trois variables et un comportement, en utilisant le contrôleur d'objet $ scope et la vue, qui se parlent. L'objet $ scope est utilisé pour transmettre des données et un comportement à la vue. Il colle la vue et le contrôleur ensemble.

Essentiellement, l'objet $ scope effectue les tâches suivantes:

  1. Passer les données du contrôleur à la vue

  2. Passer le comportement du contrôleur à la vue

  3. Colle le contrôleur et la vue ensemble

  4. L'objet $ scope est modifié lorsqu'une vue change et une vue est modifiée lorsque les propriétés de l'objet $ scope changent

Nous attachons des propriétés à un objet $ scope pour transmettre des données et un comportement à la vue. Avant d'utiliser l'objet $ scope dans le contrôleur, nous devons le passer dans la fonction de contrôleur en tant que dépendances.

Utilisation de la syntaxe «controller as» et de vm

Nous pouvons réécrire le contrôleur ci-dessus en utilisant le contrôleur comme syntaxe et la variable vm comme indiqué dans la liste ci-dessous:

myApp.controller("AddVMController", function () {

    var vm = this;

    vm.number1 = undefined;

    vm.number2=undefined;

    vm.result =undefined;

    vm.add = function () {

        vm.result = vm.number1 + vm.number2;

    }

});

Essentiellement, nous attribuons ceci à une variable vm, puis nous y attachons une propriété et un comportement. Sur la vue, nous pouvons accéder à AddVmController en utilisant le contrôleur comme syntaxe. Ceci est montré dans la liste ci-dessous:

<div ng-controller="AddVMController as vm">

            <input ng-model="vm.number1" type="number" />

            <input ng-model="vm.number2" type="number" />

            <button class="btn btn-default" ng-click="vm.add()">Add</button>

            <h3>{{vm.result}}</h3>

  </div>

Bien sûr, nous pouvons utiliser un autre nom que «vm» dans le contrôleur comme syntaxe. Sous le capot, AngularJS crée l'objet $ scope et attache les propriétés et le comportement. Cependant, en utilisant le contrôleur comme syntaxe, le code est très propre au niveau du contrôleur et seul le nom d'alias est visible sur la vue.

Voici quelques étapes pour utiliser le contrôleur comme syntaxe:

  1. Créez un contrôleur sans objet $ scope.

  2. Affectez-le à une variable locale. J'ai préféré le nom de variable comme vm, vous pouvez choisir n'importe quel nom de votre choix.

  3. Attachez les données et le comportement à la variable vm.

  4. Sur la vue, donnez un alias au contrôleur en utilisant le contrôleur comme syntaxe.

  5. Vous pouvez donner n'importe quel nom à l'alias. Je préfère utiliser vm sauf si je ne travaille pas avec des contrôleurs imbriqués.

Lors de la création du contrôleur, il n'y a pas d'avantages ou d'inconvénients directs à utiliser l'approche objet $ scope ou le contrôleur comme syntaxe. C'est purement une question de choix, cependant, l'utilisation du contrôleur comme syntaxe rend le code JavaScript du contrôleur plus lisible et évite tout problème lié à ce contexte.

Contrôleurs imbriqués dans l'approche objet $ scope

Nous avons deux contrôleurs comme indiqué dans la liste ci-dessous:

myApp.controller("ParentController", function ($scope) {



    $scope.name = "DJ";

    $scope.age = 32;

});

myApp.controller("ChildController", function ($scope) {



    $scope.age = 22;

    $scope.country = "India";



});

La propriété «age» se trouve à l'intérieur des deux contrôleurs, et sur la vue, ces deux contrôleurs peuvent être imbriqués comme indiqué dans la liste ci-dessous:

<div ng-controller="ParentController">



            <h2>Name :{{name}} </h2>

            <h3>Age:{{age}}</h3>



             <div ng-controller="ChildController">

                    <h2>Parent Name :{{name}} </h2>

                    <h3>Parent Age:{{$parent.age}}</h3>

                    <h3>Child Age:{{age}}</h3>

                    <h3>Country:{{country}}</h3>

             </div>

        </div>

Comme vous le voyez, pour accéder à la propriété age du contrôleur parent, nous utilisons le $ parent.age. La séparation des contextes n'est pas très claire ici. Mais en utilisant le contrôleur comme syntaxe, nous pouvons travailler avec des contrôleurs imbriqués d'une manière plus élégante. Disons que nous avons des contrôleurs comme indiqué dans la liste ci-dessous:

myApp.controller("ParentVMController", function () {

    var vm = this;

    vm.name = "DJ";

    vm.age = 32;

});

myApp.controller("ChildVMController", function () {

    var vm = this;

    vm.age = 22;

    vm.country = "India";



});

Sur la vue, ces deux contrôleurs peuvent être imbriqués comme indiqué dans la liste ci-dessous:

<div ng-controller="ParentVMController as parent">



            <h2>Name :{{parent.name}} </h2>

            <h3>Age:{{parent.age}}</h3>



            <div ng-controller="ChildVMController as child">

                <h2>Parent Name :{{parent.name}} </h2>

                <h3>Parent Age:{{parent.age}}</h3>

                <h3>Child Age:{{child.age}}</h3>

                <h3>Country:{{child.country}}</h3>

            </div>

 </div>

Dans le contrôleur comme syntaxe, nous avons un code plus lisible et la propriété parent est accessible en utilisant le nom d'alias du contrôleur parent au lieu d'utiliser la syntaxe $ parent.

Je conclurai cet article en disant que c'est uniquement à vous de choisir si vous voulez utiliser le contrôleur comme syntaxe ou l'objet $ scope. Il n'y a ni avantage ni inconvénient énorme, simplement que le contrôleur en tant que syntaxe que vous contrôlez sur le contexte est un peu plus facile à utiliser, étant donné la séparation claire des contrôleurs imbriqués sur la vue.

ShibinRagh
la source
4

Je trouve que le principal avantage est une API plus intuitive car les méthodes / propriétés sont associées directement à l'instance du contrôleur et non à l'objet scope. Fondamentalement, avec l'ancienne approche, le contrôleur devient simplement une décoration pour la construction de l'objet scope.

Voici quelques informations supplémentaires à ce sujet: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff

TGH
la source
3

D'après ce que j'ai lu, $ scope sera supprimé dans Angular 2.0, ou du moins comment nous voyons l'utilisation de $ scope. Il pourrait être bon de commencer à utiliser le contrôleur à l'approche de la sortie de 2.0.

Lien vidéo ici pour plus de discussion à ce sujet.

jason328
la source