Sintassi "controller as" di AngularJs - chiarimento?


121

Ho letto della nuova sintassi da angularJS per quanto riguardacontroller as xxx

La sintassi InvoiceController as invoicedice ad Angular di istanziare il controller e salvarlo nella fattura variabile nell'ambito corrente.

Visualizzazione:

inserisci qui la descrizione dell'immagine

Ok, quindi non avrò il parametro $scopenel mio controller e il codice sarà molto più pulito nel controller.

Ma

Dovrò specificare un altro alias nella vista

Quindi fino ad ora ho potuto fare:

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

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

E ora posso fare:

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

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

Domanda

Qual è l'obiettivo di farlo? rimuovendo da un posto e aggiungendo a un altro posto?

Sarò felice di vedere cosa mi sto perdendo.


8
Questo video lo spiega molto bene. youtube.com/watch?v=tTihyXaz4Bo Penso che sia usato per un codice più pulito nell'HTML.
Fizer Khan

1
Chiarezza. Non mi preoccupo di usare $ scope.x vs this.x nel controller, ma a mio avviso l'associazione a {{invoice.x}} mi dice più di {{x}} (imho). Inoltre, mi chiedo se questo risolva un problema di cui ho sentito parlare in angolare in cui i non oggetti nel controller hanno problemi (quindi things.x andrebbe bene, ma x causerebbe un problema).
Matt Roberts

1
@ MattRoberts per rispondere al tuo ultimo commento: il problema non oggetto a cui fai riferimento non è un problema angolare tanto quanto un fatto di eredità prototipica di javascript. C'è una buona spiegazione del motivo per cui accade in angolare qui (insieme al motivo per cui lo controller asrisolve).
Russ Matney il

Come sostituirò $ scope. $ Broadcast? in questo nuovo caso perché la mia trasmissione this. $ non sembra funzionare
Gaurav

1
@ Gaurav puoi ancora iniettare il servizio $ scope nel tuo controller, anche se usi il controller come sintassi per alcune proprietà, metodi, ecc.
Derek

Risposte:


163

Ci sono molte cose al riguardo.

Ad alcune persone non piace la $scopesintassi (non chiedermi perché). Dicono che potrebbero semplicemente usare this. Quello era uno degli obiettivi.

Anche chiarire da dove proviene una proprietà è molto utile.

Puoi annidare i controller e durante la lettura dell'html è abbastanza chiaro da dove viene ogni proprietà.

Puoi anche evitare alcuni dei problemi con le regole dei punti .

Ad esempio, avendo due controller, entrambi con lo stesso nome "nome", puoi farlo:

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

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

Puoi modificare sia il genitore che il figlio, nessun problema al riguardo. Ma devi usare $parentper vedere il nome del genitore, perché l'hai nascosto nel controller del tuo bambino. In un codice html massiccio $parentpotrebbe essere problematico, non sai da dove viene quel nome.

Con controller aspuoi fare:

<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>

Stesso esempio, ma è molto più chiaro da leggere.


10
Anche qui c'è un buon esempio del perché questo approccio potrebbe creare confusione per alcuni: stackoverflow.com/questions/25405543/…
Julian Hollmann

Questo è molto utile quando si annidano i controller!
C_J

1
Ho problemi con un'implementazione simile della tua risposta, consulta stackoverflow.com/questions/38315538
Cody,

Ciò consente anche di utilizzare una classe es6 come controller e fare riferimento ai metodi nell'HTML. foo() { ... }è molto più pulito di $scope.foo = function() { ... }.
Brian McCutchon

17

Il vantaggio principale della controller assintassi che vedo è che puoi lavorare con i controller come classi, non solo con alcune funzioni di decorazione di $ scope, e sfruttare l'ereditarietà. Spesso mi imbatto in una situazione in cui è presente una funzionalità molto simile a un numero di controller e la cosa più ovvia da fare è creare una BaseControllerclasse ed ereditarla.

Anche se c'è l'ereditarietà di $ scope, che risolve parzialmente questo problema, alcune persone preferiscono scrivere il codice in un modo più OOP, il che, a mio parere, rende il codice più facile da ragionare e testare.

Ecco un violino da dimostrare: http://jsfiddle.net/HB7LU/5796/


1
Questo dovrebbe ottenere più voti positivi, poiché il violino è davvero utile
Mawg dice reintegrare Monica il

13

Credo che un vantaggio particolare sia chiaro quando si hanno ambiti nidificati. Ora sarà completamente chiaro esattamente da quale ambito proviene un riferimento di proprietà.


7

fonte

Differenza tra la creazione di un controller utilizzando $scope objecte utilizzando la “controller as”sintassi e vm

Creazione di un controller utilizzando l'oggetto $ scope

Di solito creiamo un controller utilizzando l'oggetto $ scope come mostrato nell'elenco seguente:

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



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

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

    }

});

Sopra stiamo creando l'AddController con tre variabili e un comportamento, usando il $ scope object controller e la vista, che dialogano tra loro. L'oggetto $ scope viene utilizzato per trasmettere dati e comportamento alla vista. Incolla la vista e il controller insieme.

Essenzialmente l'oggetto $ scope esegue le seguenti attività:

  1. Passa i dati dal controller alla visualizzazione

  2. Passa il comportamento dal controller alla vista

  3. Incolla il controller e la vista insieme

  4. L'oggetto $ scope viene modificato quando una vista cambia e una vista viene modificata quando le proprietà dell'oggetto $ scope cambiano

Alleghiamo proprietà a un oggetto $ scope per passare dati e comportamento alla vista. Prima di utilizzare l'oggetto $ scope nel controller, è necessario passarlo nella funzione controller come dipendenze.

Utilizzando la sintassi "controller as" e vm

Possiamo riscrivere il controller sopra usando il controller come sintassi e la variabile vm come mostrato nell'elenco seguente:

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;

    }

});

Essenzialmente lo stiamo assegnando a una variabile vm e quindi alleghiamo una proprietà e un comportamento a quella. Nella vista possiamo accedere all'AddVmController usando il controller come sintassi. Questo è mostrato nell'elenco seguente:

<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>

Ovviamente possiamo usare un nome diverso da "vm" nel controller come sintassi. Dietro le quinte, AngularJS crea l'oggetto $ scope e allega le proprietà e il comportamento. Tuttavia, utilizzando il controller come sintassi, il codice è molto pulito nel controller e solo il nome alias è visibile nella vista.

Di seguito sono riportati alcuni passaggi per utilizzare il controller come sintassi:

  1. Crea un controller senza oggetto $ scope.

  2. Assegnalo a una variabile locale. Ho preferito il nome della variabile come vm, puoi scegliere qualsiasi nome a tua scelta.

  3. Allega dati e comportamento alla variabile vm.

  4. Nella vista, assegna un alias al controller utilizzando il controller come sintassi.

  5. Puoi dare qualsiasi nome all'alias. Preferisco usare VM a meno che non stia lavorando con controller annidati.

Nella creazione del controller, non ci sono vantaggi o svantaggi diretti nell'usare l'approccio all'oggetto $ scope o il controller come sintassi. È puramente una questione di scelta, tuttavia, l'utilizzo del controller come sintassi rende il codice JavaScript del controller più leggibile e previene qualsiasi problema relativo a questo contesto.

Controller annidati nell'approccio agli oggetti $ scope

Abbiamo due controller come mostrato nell'elenco seguente:

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



    $scope.name = "DJ";

    $scope.age = 32;

});

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



    $scope.age = 22;

    $scope.country = "India";



});

La proprietà "età" è all'interno di entrambi i controller e nella vista questi due controller possono essere nidificati come mostrato nell'elenco seguente:

<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>

Come puoi vedere, per accedere alla proprietà age del controllore genitore stiamo usando $ parent.age. La separazione del contesto non è molto chiara qui. Ma usando il controller come sintassi, possiamo lavorare con controller annidati in un modo più elegante. Supponiamo di avere controller come mostrato nell'elenco seguente:

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";



});

Nella vista questi due controller possono essere annidati come mostrato nell'elenco seguente:

<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>

Nel controller come sintassi, abbiamo un codice più leggibile ed è possibile accedere alla proprietà padre utilizzando il nome alias del controller padre invece di utilizzare la sintassi $ parent.

Concluderò questo post dicendo che è puramente una tua scelta se vuoi usare il controller come sintassi o l'oggetto $ scope. Non c'è alcun enorme vantaggio o svantaggio in nessuno dei due, semplicemente che il controller come sintassi che hai il controllo sul contesto è un po 'più facile da lavorare, data la netta separazione nei controller annidati nella vista.


4

Trovo che il vantaggio principale sia un'API più intuitiva poiché i metodi / proprietà sono associati direttamente all'istanza del controller e non all'oggetto ambito. Fondamentalmente, con il vecchio approccio, il controller diventa solo un decoro per costruire l'oggetto scope.

Ecco alcune ulteriori informazioni su questo: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff


3

Da quello che ho letto, $ scope verrà rimosso in Angular 2.0, o almeno come vediamo l'uso di $ scope. Potrebbe essere utile iniziare a utilizzare il controller all'avvicinarsi del rilascio di 2.0.

Link al video qui per ulteriori discussioni su di esso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.