如何在其他地方处理角度服务变更?

时间:2016-03-25 07:40:46

标签: angularjs angularjs-service

AngularJS中常见的做法是为DOM操作制作和使用自定义服务,并在UI的不同部分共享相同的功能,我的问题也与此案例有关,如下所示:

我的应用程序中有一个侧边栏组件和一个用于最小化单击边栏的按钮,但问题是它们的控制器不同,所以我在名为sidebarService的同一模块中创建了一个服务并将此服务注入两个控制器,但是当控制器通过事件在服务中更改数据时,我无法在另一个控制器中处理它,所以如何执行此操作:

应用-module.js

(function() {
  'use strict';

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

});

边栏-service.js

(function() {
  'use strict';

  angular.module('app')
    .factory('sidebarService', function() {

    var showClass = false;

    return {

      toggle: function() {
        showClass = !showClass;
      },

      isClassShown: function() {
        return showClass;
      }

    };
  });

});

应用-controller.js

(function() {
  'use strict';

  angular.module('app')
    .controller('App', ['sidebarService', function(sidebarService) {

    var appVm = this;

    appVm.isClassShown = function() {

      return sidebarService.isClassShown();

    };

  }]);

});

导航栏-controller.js

(function() {
  'use strict';

  angular.module('app')
    .controller('Navbar', ['sidebarService', function(sidebarService) {

    var navbarVm = this;

    navbarVm.toggleSidebar = function() {

      sidebarService.toggle();

    };
  }]);

})();

的index.html

<!DOCTYPE html>
<html ng-app="app">
<head>
  <title>My App</title>
  <!-- ... -->
</head>
<body ng-controller="App as app">
  <ul ng-controller="Navbar as navbar">
    <li>
      <a href="#" ng-click="navbar.toggleSidebar()">Toggle Sidebar</a>
    </li>
    <!-- ... -->
  </ul>
  <div class="sidebar" ng-class="{mini:app.isClassShown()}">
    <!-- ... -->
  </div>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

嗯,有两种方法:

解决方案1:一个非常简单且同时典型的角度解决方案:您可以使用$scope.$watch来跟踪控制器的值。因此,在您的情况下,您需要添加到要跟踪以下观察者值的每个$scope

$scope.$watch(function() { return sidebarService.isClassShown() }, function(newValue, oldValue) {
  console.log(newValue, oldValue);
});

换句话说,在您的app-controller中:

(function() {
  'use strict';

  angular.module('app')
    .controller('App', ['$scope', 'sidebarService', function($scope, sidebarService) {

    var appVm = this;

    appVm.isClassShown = function() {

      return sidebarService.isClassShown();

    };

    $scope.$watch(function() { return sidebarService.isClassShown() }, function(newValue, oldValue) {
      console.log('changed', newValue, oldValue);
    });

  }]);

});

解决方案2:抛出角度事件并监听此事件:使用angular $ emit函数发出自定义事件。此外,第三方库可用于抛出事件,我更喜欢标准角度事件系统。

答案 1 :(得分:0)

当AngularJS范围使用原型继承概念,然后您的父范围属性将在子范围中可用但是确定时,使用父范围的属性时遇到的问题也是可能的并且是一个小解决方案从子作用域进行更改以及在父作用域中更改使用基于JavaScript对象的作用域属性。

有关此主题的更多信息,请阅读here

所以根据我的解释和建议,请按照以下步骤进行:

应用-controller.js

(function() {
  'use strict';

  angular.module('app')
    .controller('App', ['$scope', function($scope) {

    $scope.someObj = {

      sidebarClass: false

    };

  }]);

});

<强>的index.html

<!DOCTYPE html>
<html ng-app="app">
<head>
  <title>My App</title>
  <!-- ... -->
</head>
<body ng-controller="App as app">
  <ul ng-controller="Navbar as navbar">
    <li>
      <a href="#" ng-click="someObj.sidebarClass = !someObj.sidebarClass">Toggle Sidebar</a>
    </li>
    <!-- ... -->
  </ul>
  <div class="sidebar" ng-class="{mini:someObj.sidebarClass}">
    <!-- ... -->
  </div>
</body>
</html>