2014-09-03 8 views
8

ho specificato una funzione in mio controller come questo:IIFE in AngularJS

$scope.myFunction = function(){ console.log('test'); } 

voglio questa funzione per essere attivato quando un selectbox è stato modificato. Perciò io applico ng-cambiamento sull'elemento selezionare in questo modo:

<select ng-options="..." ng-model="..." ng-change="myFunction();"></select> 

Ma voglio anche la funzione myFunction per essere attivato quando la mia pagina viene caricata. Così ho pensato di trasformare la mia funzione in un IIFE:

($scope.myFunction = function(){ console.log('test'); }()); 

Tuttavia, ora la funzione viene attivata solo su pageload e non da NG-cambiamento. Ho notato che quando cambio la parentesi, la funzione anche viene innescato da NG-cambiamento:

($scope.myFunction = function(){ console.log('test'); })(); 

qualcuno può spiegare perché questo anche le questioni?

Grazie mille!

+2

che la prima chiamata non è un IIFE, la seconda è. – helpermethod

+0

@helpermethod in base a questo articolo http://benalman.com/news/2010/11/immediately-invoked-function-expression/, entrambe le versioni sono IIFE, con lievi differenze 'Tali paren indicano che l'espressione della funzione essere immediatamente invocato e la variabile conterrà il risultato della funzione, non la funzione stessa. Questo può salvare qualcuno che legge il tuo codice il problema di dover scorrere verso il basso in fondo a quella che potrebbe essere un'espressione di funzione molto lunga per vedere se è stata invocata o meno. – Alex

risposta

9

C'è una grande differenza tra questo

($scope.myFunction = function(){ console.log('test'); }()); 

E questo

($scope.myFunction = function(){ console.log('test'); })(); 

Perché la prima riga assegna il risultato della chiamata di funzione, e solo memorizza, ma non è una funzione che memorizza.

Il secondo funziona come previsto, perché si chiama la funzione dopo aver assegnato a $scope.myFunction

UPDATE

Come helpermethod rilevare nei commenti, la prima linea non è un IIFE, perché sei non chiamando la funzione stessa, ma solo il risultato di essa.

+0

Ok, ho capito. Il motivo per cui ho fatto il primo è che JSLint si lamentava di 'Bad invocation' della funzione. – PhillSlevin

5

Senza vedere tutto il codice è difficile dirlo. Non stai utilizzando un IIFE, stai eseguendo la tua funzione e impostandola sulla variabile $ scope. Inoltre, un IIFE non lo farà girare al caricamento della pagina. Invece di provare a correggere tutto, prova a utilizzare il codice più simile all'esempio seguente.

provare a creare un controller in un IIFE e aggiornare il codice HTML in questo modo:

<div ng-controller="MyCtrl as vm"> 
    <select ng-options="vm.someOptions" 
     ng-model="vm.someModel" 
     ng-change="vm.myFunction()"></select> 
</div> 

e il controller

(function(){ 
    angular.module('myapp').controller('MyCtrl', MyCtrl); 

    function MyCtrl() { 
     var vm = this; 

     vm.someModel; 
     vm.someOptions = []; // set these 
     vm.myFunction = myFunction; 

     activate(); 

     function activate() { 
      myFunction(); 
     } 

     function myFunction() { 
      // TODO: will be called onchange and 
      // when controller starts 
     } 

    } 

})();