Eredità per gli ambiti in AngularJS

In un genitore ambito controller, ho definito selectedItem, che è impostato a ‘x’. Quindi nell’ambito figlio, ho definito selectedItem utilizzando ngModel:

<div ng-app>
  <div ng-controller="CtrlA">
       <div ng-controller="CtrlB">
         <select ng-model="selectedItem" ng-options="item for item in items">
         </select>
      </div>
  </div>
</div>

function CtrlA($scope) {
    $scope.selectedItem = 'x';
    $scope.items = ['x', 'y'];
}

function CtrlB($scope) {}

Quando la pagina viene caricata, il selectedItem è correttamente impostato a ‘x’ come previsto. Quando si seleziona ‘y’, selectedItem in CtrlB $ambito dona ‘y’, come previsto.

Ma quando ho ispezionare $scope.selectedItem in CtrlA ambito di applicazione (uso di AngularJS del batarang), dona ‘x’ .

jsFiddle: http://jsfiddle.net/sudhh/GGKjp/2/

Pagina di anteprima: http://fiddle.jshell.net/sudhh/GGKjp/2/show/light/ (per l’ispezione con angularjs batarang)

Perché $scope.selectedItem in CtrlA ambito non ottenere aggiornato a “y”? Qual è la spiegazione?

Io preferisco non utilizzare eventi o rootScope per aggiornare selectedItem in ambito principale (ai fini dell’apprendimento).

Assicurarsi di leggere Overflow dello Stack domanda stackoverflow.com/questions/14049480 Che dà una buona panoramica più approfondita dell’ambito eredità in AngularJS.

OriginaleL’autore sudhakar | 2013-01-09

2 Replies
  1. 7

    Se si tenta di associare ad una primitiva dichiarato in ambito genitore, quindi il selectedItem in ambito figlio effettivamente ombra la proprietà con lo stesso nome nell’ambito padre.

    In questo caso ci sono 3 scelte

    1. definire oggetti di un genitore per il tuo modello, quindi fare riferimento a un
      proprietà di tale oggetto nel bambino: rif.selectedItem
    2. $padre.selectedItem (non sempre è possibile, ma è più facile che 1.
      dove possibile)
    3. definire una funzione in ambito padre, e la chiamata da parte del bambino,
      passando il valore primitivo fino al genitore (non sempre possibile)

    Di più sulla https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

    Potete trovare l’aggiornamento violino, utilizzando il primo approccio al http://jsfiddle.net/sudhh/XU2rP/1/

    function CtrlA($scope) {
      $scope.items = ['x', 'y'];
      $scope.ref = {
        selectedItem: 'x'
      };
    }
    Infatti, ho esteso il codice un po ‘ in questo jsFiddle utilizzando orologi che accedere alla console. Solo l’orologio in B viene attivato.

    OriginaleL’autore sudhakar

  2. 0

    Ho notato che in casi simili che AngularJS non guardare selectedItem correttamente. L’unico modo che ho trovato è quello di inizializzare selectedItem con una voce dal items array. Provare le seguenti:

    function CtrlA($scope) {
        $scope.items = ['x', 'y'];
        $scope.selectedItem = $scope.items[0];
    }
    Ancora non funziona. Se si seleziona “y” dal menu a discesa, & ispezionare il campo di applicazione, CtrlB dona ‘y’, come previsto, ma CtrlA mostra ancora selectedItem come ‘x’
    Angolare è guardando selectedItem correttamente. Il problema è che ci sono due selectedItem proprietà — nell’ambito padre e uno in ambito figlio. Angolare è la visione di entrambi, correttamente, ma in modo indipendente. A causa del modo in JavaScript ereditarietà prototipale opere, l’ambito figlio sarà solo vedere la sua proprietà, e il padre solo di sua proprietà. Quello che vuoi è quello di avere il bambino ambito di utilizzare la struttura che già esiste in ambito padre, e non creare una nuova proprietà. (Ho visto che @sudhakar già trovato la risposta, volevo solo chiarire che cosa sta succedendo.)

    OriginaleL’autore asgoth

Lascia un commento