从指令动态添加角度属性到元素

时间:2014-07-28 02:44:41

标签: angularjs angularjs-directive

我正在尝试构建一个指令,用于更改缓慢ajax调用的按钮上的加载状态。基本上,我们的想法是将一个属性“ng-loading”设置为一个按钮元素,并让该指令添加剩下的东西。

这是html代码:

<button class="btn btn-primary" name="commit" type="submit" ng-loading="signupLoading">
  Submit
</button>

这是指令代码:

.directive('ngLoading', ['$compile',  function($compile) {
  return {
    restrict: 'A',
    replace: false,
    terminal: true,
    link: function(scope, element, attrs) {
      element.attr('ng-class', '{loading:' + attrs['ngLoading'] +'}');
      element.attr('ng-disabled', attrs['ngLoading']);
      element.append(angular.element('<img class="loading-icon" src="/assets/images/loading-icon.gif"/>'));
      $compile(element.contents())(scope);
    }
  };
}]);

在呈现的HTML中看起来都是正确的,但是从指令添加的属性根本不是功能。我可以将这些属性移动到HTML代码中,一切都很好,但在许多地方这都是一些冗余的代码。

我引用了帖子Angular directive to dynamically set attribute(s) on existing DOM elements,但它并没有解决我的问题。

欢迎任何评论/建议。提前谢谢。

1 个答案:

答案 0 :(得分:24)

如果你想要的只是一些DOM操作,你不需要重新编译该指令,你可以根据范围属性的变化添加和删除类。你可以改用$ watch。

<强> JAVASCRIPT

.directive('ngLoading', function() {
  return function(scope, element, attrs) {
    var img = angular.element('<img class="loading-icon" src="/assets/images/loading-icon.gif"/>');
    element.append(img);
    scope.$watch(attrs.ngLoading, function(isLoading) {
       if(isLoading) {
         img.removeClass('ng-hide');
         element.addClass('loading');
         element.attr('disabled', '');
       } else {
         img.addClass('ng-hide');
         element.removeClass('loading');
         element.removeAttr('disabled');
       }
    });
  };
});

注意:您的代码无法正常工作,因为它会编译元素的内容,而不是元素本身,您附加了已实现的属性。

尝试$compile(elem)(scope);并且它应该正常工作,但我不推荐它,因为具有此类指令的每个元素都必须重新编译。

<强>更新: 在使用$compile之前删除属性&#39; ngLoading&#39;到元素以防止无限编译。

elem.removeAttr('ng-loading');
$compile(elem)(scope);