AngularJS 1.6:指令模板中的指令仅在第一次运行

AngularJS 1.6: Directive inside Directive Template works only first time

我有一个指令 "avatar",它接受一个 'user' 对象并显示用户的图像。

这很好用。

现在我有另一个指令 'user',它显示给定 'user' 对象的名称并在其模板中包含指令。

这有效..第一次。

当我更新 'user' 对象时,只有名称改变,图像(头像)没有改变。

我的问题:如何让它工作?

头像指令:

(link 函数:如果用户对象确实有一个 'ext' 属性,它会计算一个图像路径 ('src'),否则它会显示一个标准的 template.jpeg)

directive('avatarSmall', function() {

  return {
    restrict: "E",
    replace: true,
    templateUrl: "scripts/directives/avatar/small.html",
    link: function(scope, element, attrs) {
      var r = "images/avatars/";
      var ext = scope.user.ext;
      r += ext != undefined && ext.length >= 3 ? scope.user.ID + "." + ext : "template.jpeg";
      scope.src = r;
    },
    scope: {
      user: '='
    }
  }
})

头像模板:

<div class="circle-wrapper-small">
  <img class="circle-img-small"
       ng-src="{{src}}">
</div>

用户指令:

directive('user', function($compile) {
  return {
    restrict: "E",
    replace: true,
    templateUrl: "scripts/directives/user/template.html",
    scope: {
      user: '='
    }
  }
})

用户模板:

<div>
  <div class="media-left">
    <avatar-small user="user" />
  </div>
  <div class="media-body">
    <h4 class="media-heading">{{user.name}} {{user.surname}}</h4>
    </h5>
  </div>
</div>

因为你的 avatar 指令的代码在指令 init 上只执行一个。如果你想更新更改,你应该 $broadcast 事件到你的指令并在 $broadcast 事件上执行该代码。

有关 $emit$broadcast$on 活动的更多信息,您可以查看此 post:

像这样:

父控制器

$scope.user = {
  // object properties
}

// watch "$scope.user" for changes
$scope.$watch('user', function(newVal, oldVal){
    if(newVal !== oldVal) {
      // send new "$scope.user" to your directive
      $scope.$broadcast('userObjChanged', $scope.user);
    }
}, true);

在你的指令中

// catch event from parent's controller with new user object
$scope.$on('userObjChanged', function(event, data) {
  console.log(data); // here is the new user object from parent's scope
})