AngularJS-当指令更改服务中的数据时,视图未更新

时间:2018-07-19 20:41:02

标签: angularjs angularjs-directive angularjs-service

我正在使用指令与服务进行交互,并且在显示最新数据的视图中遇到了一些麻烦。

我设置以下示例。您可以看到,当控制器与服务交互时,视图将使用最新数据进行更新。如果单击指令链接,则可以在控制台中看到数据已更改,但视图未使用该数据更新。

http://jsfiddle.net/kisonay/pv8towqc/

我想念什么?

JavaScript

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

app.factory('Service', function() {
  var Service = {};
  Service.data = {};
  Service.data.active = false;
  Service.data.one = {};
  Service.data.many = [];
  Service.changeActive = function(state) {
    state = state || false;
    Service.data.active = state;
  };
  Service.setOne = function(one) {
    Service.data.one = one;
  };
  Service.setMany = function(many) {
    Service.data.many = many;
  };
  return Service;
});

app.directive('launcher', function(Service) {
  return {
    restrict: "A",
    link: function(scope, elem, attrs) {
      elem.bind('click', function(event) {
        if (Service.data.active) {
          Service.changeActive(false);
        } else {
          Service.changeActive(true);
        }
        console.log(Service.data); // shows data changed
      });
    }
  };
});

function Ctrl1($scope, Service) {
  $scope.ServiceData = Service.data;
}

function Ctrl2($scope, Service) {
  $scope.active = function() {
    Service.changeActive(true);
  };
  $scope.inactive = function() {
    Service.changeActive(false);
  };
}

HTML

<div ng-controller="Ctrl1">
  {{ServiceData}}
</div>

<hr />

<div ng-controller="Ctrl2">
  Directive: <a href="#" launcher>Change</a>
  <hr /> Controller:

  <button ng-click="active()">
    Active
    </button>
  <button ng-click="inactive()">
    Inactive
    </button>
</div>

2 个答案:

答案 0 :(得分:3)

您的事件侦听器会执行,但Angular对此一无所知,因此不知道它必须检测更改。

在点击侦听器的evn处添加scope.$apply();,它将按预期运行。

答案 1 :(得分:0)

app.directive('launcher', function(Service) {
  return {
    restrict: "A",
    link: function(scope, elem, attrs) {
      elem.bind('click', function(event) {
        scope.$apply(function() {
          if (Service.data.active) {
            Service.changeActive(false);
          } else {
            Service.changeActive(true);
          }
        });
      });
    }
  };
});