最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular: Watch Service for data changes? - Stack Overflow

programmeradmin2浏览0评论

I have a service defined as something like this:

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

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

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

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

In another controller, I access the data as follows:

$scope.contacts = SharedData.getContacts();

This is all well and good - but I'd like $scope.contacts to be alerted and update it's data whenever the data in SharedData changes.

How do I acplish this?

I have a service defined as something like this:

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

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

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

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

In another controller, I access the data as follows:

$scope.contacts = SharedData.getContacts();

This is all well and good - but I'd like $scope.contacts to be alerted and update it's data whenever the data in SharedData changes.

How do I acplish this?

Share Improve this question asked May 2, 2015 at 0:02 opticonopticon 3,6145 gold badges40 silver badges68 bronze badges 1
  • 1 you could use an event... – Daniel A. White Commented May 2, 2015 at 0:06
Add a ment  | 

3 Answers 3

Reset to default 3

Try an explicit watch:

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

If elements of the collection can change without the entire collection object changing identity (I assume an Array or Object), you'll need to use $scope.$watchCollection, though that is substantially slower than plain $watch, so avoid if you can make the entire collection change at once.

Note that it might be nicer design to expose a function to the scope that simply returns the current contacts:

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

If you need notification within SharedData, you can inject $rootScope into it and put the $watch onto that.

Be wary of abusing it, but this is just the sort of thing that $rootScope is for:

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

Now, in any scope you'd like, you can register for this event:

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

One way to do this would be to define a function in your service which lets you register a callback to be called when setContacts is called (onContactsUpdated below). This solution is not perfect (for example, it only lets you register a single 'handler'), but should get you on the right track. You could tweak it if it needs to be used in multiple places.

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
    };
});

Then in your controller:

SharedData.onContactsUpdated(function(){
    //do something with updated SharedData.getContacts()
});
发布评论

评论列表(0)

  1. 暂无评论