2015-05-02 18 views
5

Tôi có một dịch vụ được định nghĩa là một cái gì đó như thế này:Góc: Dịch vụ xem để thay đổi dữ liệu?

appServices.service('SharedData', function() { 
    var data = {}; 

    function setContacts(contacts) { 
     data.contacts = contacts; 
    }; 

    function getContacts() { 
     return data.contacts; 
    }; 

    return { 
     setContacts: setContacts, 
     getContacts: getContacts 
    }; 
}); 

Trong controller khác, tôi truy cập các dữ liệu như sau:

$scope.contacts = SharedData.getContacts(); 

này là tất cả tốt và tốt - nhưng tôi muốn $scope.contacts được cảnh báo và cập nhật dữ liệu của nó bất cứ khi nào dữ liệu trong SharedData thay đổi.

Làm cách nào để thực hiện việc này?

+1

bạn có thể sử dụng sự kiện ... –

Trả lời

2

Một cách để thực hiện việc này là xác định chức năng trong dịch vụ của bạn, cho phép bạn đăng ký gọi lại để gọi khi setContacts được gọi (onContactsUpdated bên dưới). Giải pháp này không hoàn hảo (ví dụ, nó chỉ cho phép bạn đăng ký một 'trình xử lý'), nhưng sẽ giúp bạn đi đúng hướng. Bạn có thể tinh chỉnh nó nếu nó cần được sử dụng ở nhiều nơi.

appServices.service('SharedData', function() { 
    var data = {}; 

    function setContacts(contacts) { 
     data.contacts = contacts; 
     if(typeof(data.contactsUpdatedCallback) !== "undefined"){ 
      data.contactsUpdatedCallback(); 
     } 
    }; 

    function getContacts() { 
     return data.contacts; 
    }; 

    function onContactsUpdated(callback){ 
     data.contactsUpdatedCallback = callback; 
    }; 

    return { 
     setContacts: setContacts, 
     getContacts: getContacts, 
     onContactsUpdated: onContactsUpdated 
    }; 
}); 

Sau đó, trong điều khiển của bạn:

SharedData.onContactsUpdated(function(){ 
    //do something with updated SharedData.getContacts() 
}); 
3

Hãy thử một chiếc đồng hồ rõ ràng:

$scope.$watch(function() { return SharedData.getContacts(); }, function(newContacts) { // Do something with newContacts. });

Nếu các yếu tố của bộ sưu tập có thể thay đổi mà không cần toàn bộ đối tượng bộ sưu tập thay đổi danh tính (tôi giả sử an Array hoặc Object), bạn sẽ cần phải sử dụng $scope.$watchCollection, mặc dù đó là chậm hơn đáng kể t han plain $watch, vì vậy tránh nếu bạn có thể thay đổi toàn bộ bộ sưu tập cùng một lúc.

Lưu ý rằng nó có thể là thiết kế đẹp hơn để lộ một hàm đến phạm vi mà chỉ đơn giản trả về địa chỉ liên lạc hiện tại:

$scope.getContacts = function() { return SharedData.getContacts(); };

Nếu bạn cần thông báo trong vòng SharedData, bạn có thể tiêm $rootScope vào nó và đặt $watch vào đó.

+0

Với cảnh báo rằng một chiếc đồng hồ đơn giản sẽ không kích hoạt nếu một liên hệ riêng lẻ đã được cập nhật. Bạn cần sử dụng '$ scope. $ WatchCollection' nếu bạn cũng quan tâm đến điều đó. – floribon

+0

@floribon Tôi không quan tâm đến việc sử dụng '$ watch' theo cách này - chạy một phương thức như vậy trên mọi chu kỳ tiêu hóa dường như sai. Tuy nhiên, cách dịch vụ được viết, một '$ watch' đơn giản sẽ hoạt động vì toàn bộ bộ sưu tập sẽ được reseated mỗi lần với' setContacts'. Tôi hy vọng bạn sẽ đồng ý rằng '$ watchCollection' là một cách rất đau đớn để đi, vì nó có khả năng lặp đi lặp lại thông qua mỗi đứa trẻ tìm kiếm những thay đổi. http://jsperf.com/angularjs-watchcollection-on-large-dataset –

+0

Tuyệt vời! Tôi mới đến Angular và đã viết câu trả lời của tôi mà không biết về điều này. –

3

Hãy cảnh giác với lạm dụng nó, nhưng điều này chỉ là loại điều mà $rootScope dành cho:

appServices.service('SharedData', function($rootScope) { 
    var data = {}; 
    function setContacts(contacts) { 
    data.contacts = contacts; 
    $rootScope.$broadcast('contacts-changed', contacts); 
    }; 
    ... 

Bây giờ, trong bất kỳ phạm vi bạn muốn, bạn có thể đăng ký cho sự kiện này:

function($scope) { 
    $scope.$on('contacts-changed', function(eventObj) {...}); 
} 
+0

Cảm ơn tuyệt vời. Có thông qua trong var 'nv' có bất kỳ ý nghĩa đặc biệt? – Jibran

+0

Ha! Bạn đã mắc lỗi. Tôi sử dụng 'nv' để đại diện cho" giá trị mới ", nhưng trong trường hợp này, nó được đặt tên tốt hơn như' evt', và là đối tượng sự kiện: https://docs.angularjs.org/api/ng/type/$ rootScope.Scope –

+0

Điều đó có ý nghĩa hơn, cảm ơn. Một câu hỏi khác: điều gì sẽ được coi là lạm dụng kỹ thuật này? Tôi cuối cùng sẽ sử dụng nó để phát sóng một tá hoặc nhiều hơn "thay đổi" sự kiện. – Jibran

Các vấn đề liên quan