16

Non sono sicuro che ciò sia effettivamente possibile, ma essenzialmente sto cercando di annullare l'ambito "&" in AngularJS. Ecco un Plunkr da dimostrare.L'ambito isolato della direttiva di accesso dall'interno del contenuto escluso

Fondamentalmente, ho impostato una direttiva personalizzata che fornisce alcuni HTML riutilizzabili. Utilizza ng-transclude per consentire il rendering di alcuni contenuti esterni al suo interno. Tuttavia, ho trovato una situazione in cui vorrei accedere a una funzione che è stata impostata sull'isolamento dell'isolamento per la direttiva, all'interno della sezione del codice transclusa.

Quindi, in sostanza ho qualcosa che assomiglia:

<div ng-controller="MainController"> 

    <!-- The directive --> 
    <div some-custom-directive> 

     <!-- Button 1 that invokes a method within the controller scope --> 
     <button id="button1" ng-click="invoke1()">Invoke from Controller</button> 

     <!-- Button 2 that invokes a method on the isolate scope for the custom directive --> 
     <button id="button2" ng-click="invoke2()">Invoke from Isolate Scope</button> 
    </div> 
</div> 

Qualcuno sa se questo è davvero possibile?

Aggiornamento

Come per la risposta di @ Mark Rajcok, il $$prevSibling trovato sul $scope può essere utilizzato per accedere al campo di applicazione isolare della direttiva, dal all'interno del contenuto transclusa. Tuttavia, ho aggiornato il suddetto Plunkr per tentare ciò da una direttiva ng-repeat, che non funziona. Suppongo che gli oggetti all'interno di quella ripetizione non ereditino l'ambito.

risposta

20

Anche se possibile, la soluzione presento è un hack, in quanto utilizza una variabile interna ambito, $$prevSibling.

All'interno del contenuto escluso, ci si trova all'interno dell'ambito transcluso. Gli ambiti isolato e transuso della direttiva sono fratelli. Per ottenere dall'ambito transclusato all'ambito isolato, è possibile utilizzare $$prevSibling. (Per ottenere dall'ambito isolato all'ambito transcluso, è possibile utilizzare $$nextSibling.)

Quindi, questo hack funziona:

<a href="" ng-click="$$prevSibling.action()">Invoke the Directive Action</a> 

Per chiamare un metodo su nell'ambito del controllore, è necessario specificare che l'uso & come @ganaraj già dimostrato:

<content-presenter controller-action="action()"> 

Poi, nel la tua direttiva:

scope: { controllerAction: '&' }, 
template: ... + 
    '<button ng-click="controllerAction()">Trigger Ctrl action()</button>' ... 

Plunker


Con ng-repeat (vedere il commento di Samuel), ogni elemento crea un ambito secondario dell'ambito transcluso. Nell'immagine qui sotto, mostro solo uno item per mantenere l'immagine più piccola. Rovescia la freccia marrone nextSibling brown per $$ prevSibling.

enter image description here

Così l'hack per arrivare al metodo action() definita sulla portata isolato da un campo di applicazione bambino ng-ripetizione è

<div ng-repeat="item in items" ng-click="$parent.$$prevSibling.action()"> 

Aggiornamento per angolare v1.3 +:

Dal momento che Angular v1.3, l'ambito transuso è ora figlio dell'isolato della direttiva scope – non sono più fratelli. Quindi, per ottenere dall'ambito transclusato all'ambito isolato, utilizzare $parent.

Con ng-repeat, ogni elemento crea ancora un ambito figlio della portata transclusa:

enter image description here

Ma per arrivare al metodo action() definita sulla portata isolato da un campo di applicazione bambino ng-repeat, abbiamo ora utilizzare

<div ng-repeat="item in items" ng-click="$parent.$parent.action()"> 
+0

Cheers, che ha funzionato. Tuttavia, ho scoperto che non funziona all'interno di un 'ng-repeat' (presumo perché ogni elemento non eredita' $ scope' dal controller.È comunque che ogni elemento può accedere a '$$ prevSibling '? Ho aggiornato il Plunkr sopra per dare un esempio –

+0

@ SamuelSlade, vedere la mia risposta aggiornata (con foto) –

+0

Brillante, funziona come un incantesimo! Grazie per il diagramma, molto informativo –

1

Ecco un plunk che risolve il problema corrente. Non sono sicuro di cosa stai tentando di fare. Ma per quanto ne so, non c'è modo di chiamare qualcosa in un ambito isolato da un ambito esterno. Naturalmente, è possibile impostare una variabile legata a due vie tra l'ambito isolato e l'ambito esterno, modificare la variabile nell'ambito esterno e $ guardarlo per l'ambito isolato (funzionerà come un meccanismo di evento) ... Quello è uno modo di fare ciò che stai tentando di fare .. se insisti su di esso.

In alternativa, esiste un meccanismo per chiamare una funzione sull'ambito esterno dall'ambito isolato. È come un richiamo.

Vedi questo http://plnkr.co/edit/5MT4vo9qXtV6nQikfEiH?p=preview

1

E 'la mia comprensione che l'aggiunta di ng-repeat a un elemento crea un nuovo ambito, in modo che il contenuto di ripetizione di essere vincolato in modo corretto. Potrebbe essere necessario un ulteriore $parent in tale catena, ad esempio $parent.$$nextSibling, per passare al livello adiacente all'ambito di isolamento della direttiva.

Problemi correlati