Angular指令如何向元素添加属性?

54

我想知道如何使用这段代码:

//html
<div ng-app="app">
    <div ng-controller="AppCtrl">
        <a my-dir ng-repeat="user in users">{{user.name}}</a>
    </div>
</div>

//js
var app = angular.module('app', []);
app.controller("AppCtrl", function ($scope) {
    $scope.users = [{name:'John',id:1},{name:'anonymous'}];
    $scope.fxn = function() {
        alert('It works');
    };

})  
app.directive("myDir", function ($compile) {
    return {
        link:function(scope,el){
            el.attr('ng-click','fxn()');
            //$compile(el)(scope); with this the script go mad 
        }
     };
});

我知道这与编译阶段有关,但我不明白重点在哪里,能否简单解释一下?


可能是在AngularJs中装饰ng-click指令的重复问题。 - Paul Sweatte
2个回答

89

一个指令,将另一个指令添加到同一个元素中:

类似的答案:

这里有一个 Plunker: http://plnkr.co/edit/ziU8d826WF6SwQllHHQq?p=preview

app.directive("myDir", function($compile) {
  return {
    priority:1001, // compiles first
    terminal:true, // prevent lower priority directives to compile after it
    compile: function(el) {
      el.removeAttr('my-dir'); // necessary to avoid infinite compile loop
      el.attr('ng-click', 'fxn()');
      var fn = $compile(el);
      return function(scope){
        fn(scope);
      };
    }
  };
});

更简洁的解决方案-不使用ngClick:

一个 Plunker: http://plnkr.co/edit/jY10enUVm31BwvLkDIAO?p=preview

app.directive("myDir", function($parse) {
  return {
    compile: function(tElm,tAttrs){
      var exp = $parse('fxn()');
      return function (scope,elm){
        elm.bind('click',function(){
          exp(scope);
        });  
      };
    }
  };
});

1
使用 ng-repeat 并在指令的控制器上调用函数时,有任何想法为什么这不起作用吗?我修改了您的 plunker 来展示我的意思。请注意,现在在单击时调用的方法位于指令的控制器上。另请注意,“This works”链接未嵌套在 ng-repeat 中,而其他链接则不起作用:http://plnkr.co/edit/Y4ADmznnDCZvuxJrcZQ0?p=preview - Jim Cooper
删除“my-dir”会破坏我的CSS规范。有什么解决方法吗?谢谢。 - Dinesh
1
@Dinesh var fn = $compile(el, null, 1001); 并保留 my-dir 属性不变。 - André Werlang
在当前编译的元素上简单调用$compile()是不正确的,这将重新编译其他优先级更高的无关指令。 - André Werlang
也许这是一个新手问题,但为什么你将“作用域”作为“exp”的参数传递? - Ian Delairre
显示剩余3条评论

2
您可以尝试这个:
<div ng-app="app">
    <div ng-controller="AppCtrl">
        <a my-dir ng-repeat="user in users" ng-click="fxn()">{{user.name}}</a>
    </div>
</div>

<script>
var app = angular.module('app', []);

function AppCtrl($scope) {
        $scope.users = [{ name: 'John', id: 1 }, { name: 'anonymous' }];
        $scope.fxn = function () {
            alert('It works');
        };
    }

app.directive("myDir", function ($compile) {
    return {
        scope: {ngClick: '='}
    };
});
</script>

属性应该是动态添加的,而不是从模板中添加的。 - codesnooker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接