0

当涉及到语法时,我有点困惑,controller as因为我以前从未使用过它。我想知道解决这个问题的正确方法。搜索时无法找到类似的问题。

我有一个菜单和一个切换菜单的按钮。菜单有自己的范围,按钮有另一个,因为它们存在于两个单独的文件和容器中。

当我单击按钮时,它只会更新nav.isActive按钮范围内的。我创建了一个用于存储状态的服务,当我想到它时我不应该这样做.. 我应该吗?因为观察该值是否发生变化的唯一方法是使用观察者,这需要我使用,$scope因为this没有该$watch功能,但是,我想尽可能避免这种情况,因为它会影响性能,即在这个项目中很重要。

controller as使用语法时从另一个“范围”更新“范围”变量的正确方法是什么?

控制器:

nav.controller('NavCtrl', ['navState', function(navState) {

  var nav = this;

  nav.menu = [
    {icon: 'color_lens', href: ''},
    {icon: 'color_lens', href: 'about'},
    {icon: 'color_lens', href: 'contact'},
    {icon: 'color_lens', href: 'logout'},
    {icon: 'color_lens', href: 'faq'}
  ];

  nav.toggleMenu = function() {
    nav.isActive = navState.checkState();
  }

}]);

将值从一个范围传递到另一个范围的服务:

nav.service('navState', [function() {

  var isActive = false;

  this.checkState = function() {

    isActive = !isActive;

    return !isActive;
  }
}]);

菜单标记(menu.html):

<nav class="si-wrapper si-dark" ng-controller="NavCtrl as nav" ng-class="{active: nav.isActive}">
  <ul class="si-list">
    <li class="si-item" ng-repeat="item in nav.menu">
      <a href="#/{{item.href}}">
        <div class="si-inner-item">
          <i class="material-icons md-36" ng-bind="item.icon"></i>
        </div>
      </a>
    </li>
  </ul>
  <h1>{{nav.isActive}}</h1> <!-- This doesn't change -->
</nav>

切换菜单的按钮(header.html):

<div ng-controller="NavCtrl as nav">
  <button ng-click="nav.toggleMenu()">Toggle</button>
  <span>{{nav.isActive}}</span> <!-- This updates however -->
</div>
4

2 回答 2

2

您的问题是nav.isActive没有为其中一个控制器设置。基本上,每当您使用ng-controller新控制器(和$scope)时,都会创建。因此,对于您的每个控制器,$scope.isActive都需要设置相关视图以引用它。

在您发布的代码中,isActive仅在toggleMenu()运行时设置,仅在 header.html 中发生。

为了让您的代码工作,只需设置isActive控制器负载。例如:

nav.controller('NavCtrl', ['navState', function(navState) {
    // put isActive on the scope on controller load
    this.activeState = navState.getState();

    nav.toggleMenu = function() {
        navState.toggleState();
    };
}]);

您需要通过分离状态访问和状态操作来使您的服务更好。还将它包装在容器对象中将确保您不会遇到任何范围层次结构问题。

nav.service('navState', [function() {

    var state = {
        isActive: false
    };

    this.toggleState = function() {
        state.isActive = !state.isActive;
    };

    this.getState = function(){
        return state;
    };
}]);

然后你需要在你的视图中使用`activeState.isActive'。

现在您将拥有一个具有可共享状态的服务,以及两个在加载时都引用相同服务的控制器。然后在您的菜单视图中,当您切换状态时,两个控制器范围都会更新。

于 2015-11-14T22:20:30.540 回答
0

来自 angularjs 文档:

当控制器通过 ng-controller 指令附加到 DOM 时,Angular 将使用指定控制器的构造函数实例化一个新的控制器对象。将创建一个新的子作用域,并作为 $scope 的控制器构造函数的可注入参数提供。

此外,ng-controller 指令具有继承自其父作用域的作用域。因此,您还可以在父项中定义共享数据。它将可以在“NavCtrl”范围内访问。但是,由于您想将控制器用作 synax,因此一种方法是在服务的帮助下共享数据。

但是,我不喜欢使用“ng-controller”指令的方法。另一种解决方案是将其替换为指令层次结构,其中子指令将需要父指令。也在那里使用'controllerAs'属性。

于 2015-11-14T23:01:36.083 回答