2013-12-12 22 views
6

In questo esempio, ho un input con una direttiva allegata. La direttiva ha lo scopo di visualizzare i messaggi accanto all'input. C'è un altro input e un pulsante per aggiungere messaggi. Una volta visualizzati alcuni messaggi, concentrarsi sull'input con la direttiva allegata dovrebbe cancellare i messaggi. http://jsfiddle.net/viro/WBqxf/

Quindi ho una direttiva con un modello isolato e sto cercando di aggiornare il modello quando l'elemento che ha la direttiva viene messo a fuoco. Sembra che devo avvolgere callback per eventi di portata $ applicare se voglio aggiornare il modello:.

element.on('focus',function(){ 
    scope.$apply(function(){ 
     console.log("focus !"); 
     scope.tstMsg=[]; 
    }) 
}); 

suppongo devo avvolgerla in $ applicare perché sto utilizzando callback degli eventi jqlite ed io Immagino che corrano "fuori" angularJS, ma non l'ho trovato chiaramente dichiarato nei documenti.

Sto facendo bene o è un hack?

C'è un modo migliore per farlo?

+0

usa 'ng-focus' e ti salva codice aggiuntivo per gestori di eventi extrenali http://docs.angularjs.org/api/ng.directive:ngFocus – charlietfl

+0

Ma per ogni elemento che ha la direttiva allegata, voglio lo stesso comportamento a fuoco, indipendentemente dal controller in cui si trova l'elemento. Con ngFocus, avrei bisogno che ogni elemento eseguisse una funzione che ripristina l'array di messaggi, è noioso se può essere automatizzato dalla direttiva, non è vero? –

risposta

2
scope

. $ Apply causerà l'esecuzione di $ digest in modo che tutti gli osservatori dell'ambito controllino le modifiche e attivino, ove appropriato. Poiché, come dici tu, stai solo vincolando a un evento (basta aggiungere addEventListener/attachEvent come appropriato) eseguendo l'ambito. $ Apply in questo contesto è valido.

+0

Ciò significa che i callback legati da element.on non sono "angularJS aware" ?. Non ne ero sicuro. –

+0

Sì come dici tu nella domanda dato che usa solo jqLite o jQuery (se lo includi) non è nel contesto del codice angolare. I servizi come $ http e $ timeout hanno automaticamente l'ambito. $ Applica la chiamata – shaunhusain

+0

Quindi, proprio come ci sono $ timeout invece di setTimeout; c'è qualcosa che dovrebbe essere usato al posto di element.on? –

3

Ogni volta che si utilizza una libreria di terze parti e si apportano modifiche, è necessario informare Angular chiamando lo $apply().

Come accennato @charlietfl ng-focus è ancora più facile:

Controler

$scope.focus = function() { 
    // Do something 
} 

HTML

<input ng-model="inp" tst-msg="message" ng-focus="focus()" /> 

Vedi jsFiddle

+0

Per qualche motivo, quando l'ho fatto senza $ apply, non funzionava. Devo controllare quello ng-focus non è la soluzione per me perché voglio che la direttiva sia autosufficiente. Non voglio dover codificare una funzione che resetterà i messaggi per ogni controller in cui ho un input con la direttiva allegata. –

+0

Ho aggiornato jsFiddle (rimosso $ apply()) e aggiunto ng-focus. Dare un'occhiata. Sarei confuso se funziona solo per me :) –

+1

Ho dato un'occhiata. In effetti funziona. Ma se rimuovi il ng-focus, non lo fa. Il tuo esempio mi ha aiutato a capire qualcosa: ng-focus gestito da angularJS, fa un ciclo $ digest sul focus, quindi in quel caso non ho bisogno di farlo nel callback dell'evento. Se voglio sbarazzarmi di ng-focus, ho bisogno del $ apply. –

Problemi correlati