Подтвердить что ты не робот

Угловое изменение значения триггера и наблюдаемого объекта в сервисе от контроллера

Я пытаюсь следить за изменениями в службе с контроллера. Я пробовал различные вещи, основанные на многих qns здесь, на stackoverflow, но я не смог заставить его работать.

HTML:

<div ng-app="myApp">
    <div ng-controller="MyCtrl">
        <div ng-click="setFTag()">Click Me</div>
    </div> 
</div>

JavaScript:

var myApp = angular.module('myApp',[]);

myApp.service('myService', function() {
    this.tags = {
        a: true,
        b: true
    };


    this.setFalseTag = function() {
        alert("Within myService->setFalseTag");
        this.tags.a = false;
        this.tags.b = false;

        //how do I get the watch in MyCtrl to be triggered?
    };
});


myApp.controller('MyCtrl', function($scope, myService) {

    $scope.setFTag = function() {
        alert("Within MyCtrl->setFTag");
        myService.setFalseTag();
    };        

    $scope.$watch(myService.tags, function(newVal, oldVal) {
        alert("Inside watch");
        console.log(newVal);
        console.log(oldVal);
    }, true);

});

Как заставить часы запускаться в контроллере?

jsfiddle

4b9b3361

Ответ 1

Попробуйте написать $watch следующим образом:

myApp.controller('MyCtrl', function($scope, myService) {


    $scope.setFTag = function() {
       myService.setFalseTag();
    };        

    $scope.$watch(function () {
       return myService.tags;
     },                       
      function(newVal, oldVal) {
        /*...*/
    }, true);

});

Демо Fiddle

[EDIT]

Иногда этот способ не будет работать, особенно если сервис был обновлен с 3d-участника.

Чтобы сделать это, мы должны помочь angular выполнить цикл дайджеста.

Вот пример:

На стороне обслуживания, когда мы хотим изменить значение tags, напишите что-нибудь вроде:

if($rootScope.$root.$$phase != '$apply' && $rootScope.$root.$$phase != '$digest'){
   $rootScope.$apply(function() {
     self.tags = true;
   });
 }
 else {
   self.tags = true;
  }