0

我試圖做一個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「編輯模式的變化,{{text}}佔位符不更新。另一個奇怪的是,每當scopeModel發生變化時,$$watchers對象不斷遞增。

回答

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; 
      }); 
      } 
     }); 
     } 
    }; 
    });