Confused su Angularjs ha transclusionato e isolato gli ambiti e le associazioni

Sto lottando per capire la portata dei modelli e dei loro vincoli rispetto alle direttive che hanno uno scopo limitato.

Ho capito che limitare l’ambito su una direttiva significa che controller. $ Scope e directive.scope non sono più la stessa cosa. Tuttavia, sono confuso dal modo in cui il posizionamento dei modelli all’interno del modello di direttiva o in html influisce sul binding dei dati. Sento che mi manca qualcosa di molto fondamentale e per andare avanti ho bisogno di capire questo.

Prendi il seguente codice (fiddle qui: http://jsfiddle.net/2ams6/ )

JavaScript

var app = angular.module('app',[]); app.controller('Ctrl',function($scope){ }); app.directive('testel', function(){ return { restrict: 'E', scope: { title: '@' }, transclude: true, template: '
'+ '

Template title: {{title}}

' + '

Template data.title:{{data.title}}

' + '
' } });

HTML

 

Transclude title:{{title}}

Transclude data.title:{{data.title}}

Il modello aggiorna solo {{title}} all’interno del modello e {{data.title}} nella transclusione. Perché non {{title}} nella transclusione né {{data.title}} nel modello?

Spostando l’input all’interno della transclusione in questo modo (fiddle qui: http://jsfiddle.net/eV8q8/1/ ):

 

Transclude title: {{title}}

Transclude data.title: {{data.title}}

ora significa che solo la trasposizione {{data:title}} viene aggiornata. Perché non utilizzare template {{title}} o {{data.title}} , né escludere {{title}} ?

E infine, spostando l’input all’interno del template, in questo modo (fiddle qui: http://jsfiddle.net/4ngmf/2/ ):

 template: '
' + '' + '

Template title: {{title}}

' + '

Template data.title: {{data.title}}

' + '
'

Ora significa che solo il modello {{data.title}} viene aggiornato. Di nuovo, perché non gli altri 3 attacchi?

Spero ci sia qualcosa di ovvio che mi fissa in faccia e mi manca. Se mi fai prendere questo, ti comprerò una birra, o ti darò dei punti, o qualche altra cosa del genere. Grazie molto.

I tuoi violini creano tre ambiti:

  1. un ambito associato al controller Ctrl , a causa di ng-controller
  2. una direttiva ha escluso l’ambito, a causa di transclude: true
  3. una direttiva isola l’ambito, a causa scope: { ... }

In fiddle1, prima di digitare qualsiasi cosa nella casella di testo, abbiamo il seguente:

inserisci la descrizione dell'immagine qui

L’ambito 003 è l’ambito associato al controller. Poiché non abbiamo ancora inserito nella casella di testo, non esiste alcuna proprietà di data . Nell’ambito isolato 004, vediamo che è stata creata una proprietà title , ma è vuota. È vuoto perché l’ambito genitore non ha ancora una proprietà data.title .

Dopo aver digitato il my title nella casella di testo, ora abbiamo:

inserisci la descrizione dell'immagine qui

L’ambito 003 del controller ora ha una nuova proprietà dell’object data (che è il motivo per cui è colorata in giallo), che ora ha una proprietà title impostata sul my title . Poiché il title proprietà dell’isolamento dell’isolamento è un canale dati a una via per il valore interpolato di data.title , ottiene anche il valore il my title (il valore viene colorato in giallo perché modificato).

L’ambito transcluso eredita prototipicamente dall’ambito del controller, quindi all’interno dell’HTML, l’angular può seguire la catena del prototipo e trovare $scope.data.title nell’ambito genitore (ma $scope.title non esiste lì).

Lo scope isolato ha solo accesso alle sue proprietà, quindi solo il title proprietà.

In fiddle2, prima di digitare abbiamo la stessa immagine di fiddle1.

Dopo aver digitato il my title :

inserisci la descrizione dell'immagine qui

Si noti dove è data.title la nuova proprietà data.title – sull’ambito transcluso. L’ambito isolato è ancora alla ricerca di data.title del controller, ma non è presente questa volta, quindi il valore della proprietà del title rimane vuoto.

In fiddle3, prima di digitare abbiamo la stessa immagine di fiddle1.

Dopo aver digitato il my title :

inserisci la descrizione dell'immagine qui

Si noti dove è stata data.title la nuova proprietà data.title , sull’ambito isolato. Nessuno degli altri ambiti ha accesso all’ambito isolato, quindi la stringa il my title non verrà visualizzata da nessun’altra parte.


Aggiornamento per Angular v1.2:

Con il cambiamento eed299a Angular ora cancella il punto di transclusione prima di transcluding, quindi il Template title: ... e Template data.title: ... parti non verranno visualizzate a meno che non si modifichi il modello in modo tale che ng-transclude sia di per sé, ad esempio come:

 '

Template title: {{title}}

' + '

Template data.title: {{data.title}}

' + '
'

Nell’aggiornamento seguente per Angular v1.3, è stata apportata questa modifica al modello.


Aggiornamento per Angular v1.3 +:

Dal momento che Angular v1.3, l’ambito transuso è ora figlio dell’ambito isolato della direttiva, piuttosto che un figlio dell’ambito del controller. Quindi in fiddle1, prima di digitare qualsiasi cosa:

inserisci la descrizione dell'immagine qui

Le immagini di questo aggiornamento sono disegnate con lo strumento Peri $ scope , quindi le immagini sono leggermente diverse. Il @ indica che abbiamo una proprietà dell’isolamento dell’isolato che utilizza la syntax @ e lo sfondo rosa indica che lo strumento non è stato in grado di trovare un riferimento antenato per la mapping (il che è vero, dal momento che non abbiamo ancora inserito nulla nella casella di testo ).

Dopo aver digitato il my title nella casella di testo, ora abbiamo:

inserisci la descrizione dell'immagine qui

Isolare le proprietà che utilizzano l’associazione @ mostrerà sempre il risultato della stringa interpolata nell’isolamento isolato dopo il simbolo @ . Peri $ scope è stato anche in grado di trovare questo valore stringa esatto in un ambito antenato, quindi mostra anche un riferimento a tale proprietà.

In fiddle 2, prima di digitare abbiamo la stessa immagine di fiddle1.

Dopo aver digitato il my title :

inserisci la descrizione dell'immagine qui

Si noti dove è data.title la nuova proprietà data.title – sull’ambito transcluso. L’ambito isolato è ancora alla ricerca di data.title del controller, ma non è presente questa volta, quindi il valore della proprietà del title rimane vuoto.

In fiddle3, prima di digitare abbiamo la stessa immagine di fiddle1.

Dopo aver digitato il my title :

inserisci la descrizione dell'immagine qui

Si noti dove è stata data.title la nuova proprietà data.title , sull’ambito isolato. Anche se l’ambito transclused ha accesso data.title isolato tramite la relazione $parent , non cercherà il title o data.title – guarderà solo nell’ambito del controller (cioè, seguirà l’ereditarietà prototipale), e l’ambito del controller non ha queste proprietà definite.

Dopo aver letto tutte le risposte presentate, inclusi i fantastici schemi di Mark, questa è la mia comprensione dell’ambito e dell’eredità secondo la mia domanda. Gradirei commenti su dove questo diagramma cade, in modo da poter aggiornare in modo appropriato. Spero che fornisca semplicemente una visione diversa di ciò che Mark ha presentato:

Portata dell'eredità

Ben chiesto, btw! Spero che la mia risposta sia eloquente ..

La risposta ha a che fare con il modo in cui gli elementi transclusi ottengono il loro scopo.

Per riassumere, hai due ambiti:

  1. L’ambito del controller, che ha $scope.data.title . (Aggiunto implicitamente dal tuo elemento di input )
  2. L’ambito della direttiva, che ha $scope.title .

Quando si modifica $scope.data.title del controller, anche la direttiva $scope.title cambia.

Hai anche due sezioni di HTML, il transcluded e il template. Quello che sta succedendo è che l’HTML concluso è nel campo di applicazione del controllore , e il modello HTML è nel campo della direttiva . Quindi l’HTML escluso non sa nulla del title e l’ambito del modello non sa nulla di data.title

Questo è esattamente ciò a cui era destinata la Transclusione: per consentire agli elementi figlio di una direttiva di mantenere l’ambito genitore , in questo caso l’ambito del controllore. In base alla progettazione, gli elementi esclusi non li conoscono in una direttiva e quindi non hanno accesso all’ambito della direttiva.

I modelli di direttiva, d’altro canto, avranno accesso solo al campo di applicazione della direttiva.

Ho modificato il tuo codice un po ‘per rendere i nomi un po’ più chiari (stessa funzionalità, però)

http://jsfiddle.net/yWWVs/2/