不通过服务从其他控制器更新值

时间:2016-03-22 12:20:28

标签: angularjs

我有一个控制器,用于每个视图的菜单和控制器。我想要实现的是将active类添加到菜单项,以便可视地选择活动菜单项。为了实现这一点,我创建了一个servide来存储当前菜单项(数字)。这是我的观点。

body
    div.menu(ng-controller="menuCtrl")
        ul
            li(ng-class="{selected: menuItem===0}")
                a(href='#/')
                    i.material-icons.medium visibility

            li(ng-class="{selected: menuItem===1}")
                a(href='#/posts')
                    i.material-icons.medium library_books

            li(ng-class="{selected: menuItem===2}")
                a(href='#/categories')
                    i.material-icons.medium loyalty
        span test {{menuItem}} // test menuItem variable


    div.row-fluid
        ng-view

此处的menuCtrl控制器

app.controller('menuCtrl', ['$scope', '$http', 'global', '$interval', function($scope, $http, GLOBAL, $interval ) {
    $scope.menuItem = GLOBAL.menuItem;
}])

如您所见,我将变量从服务绑定到本地$scope变量。

这是我的服务

app.factory( 'global', function( $http ) {
    return {
        menuItem: 0,
    }
})

然后在每个视图控制器中,我添加一行来为服务menuItem提供某些价值,如下所示:

app.controller('postsCtrl', ['$scope', '$http', 'global', '$location', function($scope, $http, GLOBAL, $location ) {
    // ...
    GLOBAL.menuItem = 1;
    // ...
}])

所有其他视图控制器都相同,因此menuItem为2,3,4等。

问题是即使看起来menuItem变量如果我点击几个菜单项也会改变,菜单下的值(我把测试评论放在哪里)仍然是0,结果只有第一个菜单item有active class。

为什么?

1 个答案:

答案 0 :(得分:0)

你应该使用directives而不是控制器来管理这类事情。

这是一个fiddle,其中“被选中”指令使生活变得轻松,在没有任何控制器的情况下绑定到您的状态服务。

  <ul>
    <li is-selected="1">Menu 1</li>
    <li is-selected="2">Menu 2</li>
    <li is-selected="3">Menu 3</li>
    <li is-selected="4">Menu 4</li>
  </ul>

在指令中,我们不仅反映所选状态,还通过使用$ watch并注入click事件处理程序来管理对所选项的更改:

myApp.directive('isSelected', ['myService', function(myService) {
  return {
    scope: {},
    link: function(scope, el, attrs) {
      var id = parseInt(attrs.isSelected, 10),           
      unwatch = scope.$watch(
        function() {
          return myService.menu.selected;
        },
        function(val) {       
          if (val == id)
            el.addClass("menuItemSelected")
          else
            el.removeClass("menuItemSelected")
        }),
        dst = scope.$on("$destroy", function() {    
        angular.element(el).off("click");
        unwatch();
        dst();           
      });
      angular.element(el).on("click",function() {
        scope.$apply(function() {myService.menu.selected = id;});       
      });   
    }
  }
}]);