指令不会在范围更改时刷新自身

时间:2016-12-02 17:01:42

标签: angularjs

我有一个指示来显示如下的重力:

angular.module('ngGravatar').directive('gravatar', function(){
    return {
        restrict: 'E',
        template: '<img ng-src={{gravatarUrl}}>',
        scope: {email: '='},
        controller: function($scope, md5){
            var url = 'http://www.gravatar.com/avatar/';
            $scope.gravatarUrl = url + md5.createHash($scope.email || '');
        }
    };
});

我在这个视图中使用它

<gravatar email="vm.email"></gravatar>

加载视图时,vm.email会异步更新,当其值更新时,gravatar指令不会自行更新并保留默认徽标...

如何让它自行更新?使用$scope.$watch?我认为双向数据绑定可以解决这个问题。 我有什么错过的吗?

2 个答案:

答案 0 :(得分:0)

尝试使用$ scope。$ watch来处理更改。

angular.module('ngGravatar').directive('gravatar', function()
{
    return {
        restrict: 'E',
        template: '<img ng-src={{gravatarUrl}}>',
        scope: { email: '='},
        controller: function($scope, md5){
            $scope.$watch('email', function(email) {
                if (email)
                {
                    var url = 'http://www.gravatar.com/avatar/';
                    $scope.gravatarUrl = url + md5.createHash(email || '');
                }
            });
        }
    };
});

答案 1 :(得分:0)

在异步数据到达后,您的指令不会刷新,因为它根本不知道它的到达。

它只能知道它控制器中发生的变化,而不是父控制器中发生的更新。

您可以在变量上设置监视,以便在适当的视图模型更改时使指令更新其内容。

检查以下代码段,该代码段演示了可以使用观察者跟踪外部更改,并自动跟踪内部更改,并且指令通过数据绑定功能更新其内容。

&#13;
&#13;
angular
  .module('demo', [])
  .controller('DefaultController', DefaultController)
  .directive('gravatar', gravatar);

DefaultController.$inject = ['$timeout'];

function DefaultController($timeout) {
  var vm = this;

  $timeout(function() {
    vm.gravatarName = 'gravatar.png';
  }, 500);
}

function gravatar() {
  var directive = {
    restrict: 'E',
    scope: {
      name: '='
    },
    template: '<img ng-src="{{vm.source}}"/>',
    controller: GravatarController,
    controllerAs: 'vm',
    bindToController: true,
  };

  return directive;
}

GravatarController.$inject = ['$scope', '$timeout'];

function GravatarController($scope, $timeout) {
  var vm = this;
  var URL = 'https://d13yacurqjgara.cloudfront.net/users/4085/screenshots/2072398/';

  // external changes need to be explicitly watched using watchers
  $scope.$watch('vm.name', function(newValue, oldValue) {
    if (newValue) {
      vm.source = URL + vm.name;
    }
  });

  $timeout(function() {
    // internal changes are automatically watched
    vm.source = 'https://pbs.twimg.com/profile_images/453956388851445761/8BKnRUXg.png';
  }, 2000);
}
&#13;
img {
  height: 250px;
  width: 250px;
  border: 1px solid #E6E6E6;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<div ng-app="demo">
  <div ng-controller="DefaultController as vm">
    <gravatar name="vm.gravatarName"></gravatar>
  </div>
</div>
&#13;
&#13;
&#13;