2014-09-03 16 views
8

tôi đã chỉ định một chức năng trong bộ điều khiển của tôi như thế này:IIFE trong AngularJS

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

Tôi muốn chức năng này được kích hoạt khi một selectbox đã được thay đổi. Do đó, tôi áp dụng ng-thay đổi trên phần tử chọn như sau:

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

Nhưng tôi cũng muốn chức năng myFunction được kích hoạt khi trang của tôi được tải. Vì vậy, tôi nghĩ để biến chức năng của tôi thành một IIFE:

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

Tuy nhiên, bây giờ chức năng này chỉ được kích hoạt khi tải trang và không thay đổi. tôi nhận thấy rằng khi tôi thay đổi ngoặc, chức năng cũng được kích hoạt bởi ng-change:

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

Ai đó có thể giải thích tại sao điều này thậm chí vấn đề?

Cảm ơn rất nhiều!

+2

Các gọi đầu tiên không phải là một IIFE, thứ hai là. – helpermethod

+0

@helpermethod theo bài viết này http://benalman.com/news/2010/11/immediately-invoked-function-expression/, cả hai phiên bản đều là IIFE, với những khác biệt nhỏ 'Các parens như vậy thường chỉ ra rằng biểu thức hàm sẽ được gọi ngay lập tức và biến sẽ chứa kết quả của hàm, chứ không phải chính hàm đó. Điều này có thể giúp ai đó đọc mã của bạn khi gặp phải sự cố khi phải cuộn xuống cuối biểu thức hàm rất dài để xem nó có được gọi hay không.' – Alex

Trả lời

9

Có sự khác biệt rất lớn giữa này

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

Và đây

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

Bởi vì dòng đầu tiên gán kết quả của các cuộc gọi chức năng, và sau đó chỉ lưu trữ nó, nhưng nó không phải là một chức năng nó lưu trữ.

Các công trình thứ hai như mong đợi bởi vì bạn gọi hàm sau khi đã giao nó cho $scope.myFunction

CẬP NHẬT

Như helpermethod chỉ ra trong các ý kiến, dòng đầu tiên không phải là một IIFE, bởi vì bạn không gọi chính hàm đó, mà chỉ là kết quả của nó.

+0

Ok, tôi hiểu ngay bây giờ. Lý do tại sao tôi đã làm trước đây là JSLint đã phàn nàn về 'Yêu cầu không hợp lệ' của hàm. – PhillSlevin

5

Nếu không nhìn thấy tất cả mã, thật khó để nói. Bạn không sử dụng IIFE, bạn đang thực hiện chức năng của riêng mình và đặt nó vào biến $ scope. Ngoài ra, một IIFE sẽ không làm cho nó chạy trên tải trang. Thay vì cố gắng sửa tất cả điều đó, hãy thử sử dụng mã giống như ví dụ bên dưới.

Cố gắng tạo ra một bộ điều khiển trong một IIFE và cập nhật HTML của bạn như thế này:

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

và điều khiển của bạn

(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 
     } 

    } 

})();