如何在范围更改的指令内重绘/重新创建模板?

时间:2013-05-03 23:11:52

标签: javascript angularjs angularjs-directive angularjs-scope

我正在尝试制作一个Twitter分享按钮指令,该指令会根据父模型进行更改

app.directive('twitterShare', function() {
  return {
    restrict: 'A',
    template: "<a href=\"https://twitter.com/share\" data-count=\"none\" class=\"twitter-share-button\" data-text=\"{{text}}\" data-lang=\"pt-BR\"></a>",
    scope: {
      text: '=twitterShare'
    },
    link: function($scope, $element, $attrs, $model) {
      return $scope.$watch('text', function(value) {
         //??
      });
    }
  };
});

和指令

<div twitter-share="scopeModel"></div>

$scope.text正确显示我的$scope.scopeModel,但由于twitter用iframe替换了a元素,因此该元素本身就会丢失。如何在更改时重新创建/重绘,但应用某种节流,因为重新创建iframe非常昂贵。

试图将其更改为

app.directive('twitterShare', function($compile, $timeout) {
return {
  restrict: 'A',
  scope: {
    text: '=twitterShare'
  },
  link: function($scope, element) {
    var $element;

    $element = "<a href=\"https://twitter.com/share\" data-count=\"none\" class=\"twitter-share-button\" data-text=\"{{text}}\" data-lang=\"pt-BR\"></a>";

    $scope.$watch('text', function(value) {
      if (value != null) {
        $timeout(function() {
          element.html($compile($element)($scope));
          typeof twttr !== "undefined" && twttr !== null ? twttr.widgets.load() : void 0;
        });
      }
    });
  }
};
});

$watch'ed模型第二次更改时,{{text}}占位符未更新。另一个奇怪的事情是每次scopeModel更改时,$$watchers对象都会继续递增。

1 个答案:

答案 0 :(得分:1)

答案是使用$ interpolate而不是$ compile。 $ interpolate使它能够处理字符串,并且不会像$ compile那样堆叠$$观察者,并且它在内存和CPU使用上也比$ compile更容易

app.directive('twitterShare', function($interpolate, $timeout) {
    return {
      restrict: 'A',
      scope: {
        text: '=twitterShare'
      },
      replace: true,
      template: "<div ng-bind-html-unsafe='element'></div>",
      link: function($scope, element) {
        var $element;

        $element = "<a href=\"https://twitter.com/share\" data-count=\"none\" class=\"twitter-share-button\" data-text=\"{{text}}\" data-lang=\"pt-BR\"></a>";

        $scope.$watch('text', function(value) {
          if (value != null) {
            $timeout(function() {
              $scope.element = $interpolate($element)($scope);
              typeof twttr !== "undefined" && twttr !== null ? twttr.widgets.load() : void 0;
            });
          }
        });
      }
    };
  });