角度指令控制和链接

时间:2016-03-07 15:22:35

标签: angularjs angularjs-directive angularjs-controller angular-digest angularjs-controlleras

我有像这样的标记

<i class="fa-font icon-user" wd-user-profile></i>

显示/隐藏此div

<div id="user-profile" ng-show="vm.isVisible">
  <h3>user name</h3>
  <h3>user email</h3>
  <pre>{{vm | json:3}}</pre><!-- not updating on click -->
</div>

和像这样的指令代码

angular
  .module('myApp')
  .directive('wdUserProfile', wdUserProfile);

function wdUserProfile() {
  var ddo = {
    restrict: 'A',
    templateUrl: 'app/components/_shared/_userProfile.html',
    controller: UserProfileController,
    controllerAs: 'vm',
    bindToController: true,
    link: function(scope, elem, attr, ctrl) {
      elem.bind('click', scope.vm.onIconClick);
      //elem.bind('click', ctrl.onIconClick); also doesn't work
    }
  };

  return ddo;
}

function UserProfileController() {
  var vm = this;

  vm.onIconClick = function() {
    vm.isVisible = !vm.isVisible;
    console.log(vm.isVisible);
  };
}

问题是虽然事件触发和vm.isVisible变化很好,但在视图中没有任何反应。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

在角度上下文之外运行的任何东西都不会使用角度消化系统来运行摘要周期来更新绑定。

您需要手动启动摘要周期,因为您要从事件(外部世界)更新范围。这样就会更新视图绑定。您可以使用scope.$apply() / $timeout来运行摘要周期。

elem.bind('click', function(){
    //don't forget to inject $timeout depenency.
    $timeout(scope.vm.onIconClick); //$timeout will run code in next digest
}));

当两个摘要周期发生冲突时,可能存在一种情况。只是你不能同时运行两个摘要周期。 $ timeout在这里做的是,如果假设一个摘要周期正在运行并且你试图通过使用$ timeout运行其他摘要周期,它将新的摘要周期放在一个单独的队列中,直到第一次完成,然后它评估排队的摘要周期,一次全部正在运行的摘要周期完成。