我试图从指令调用函数并传递参数。回调函数正被传递到隔离范围。我有两个问题。首先,当嵌套在ng-repeat中时,这根本不起作用,第二,即使不在ng-repeat中,我也不知道如何将参数传递给回调函数。这是一个显示问题的傻瓜:http://plnkr.co/edit/3FN0o3UE99wsmUpxMe4x?p=preview
请注意,当您单击"这适用于"时,它至少会执行父作用域中的功能,但是当点击其他作用时,它什么也不做(因为它们在内部? -重复)。这是第一个问题。
第二个问题是当你点击"这有效",即使它成功调用了该函数,我也无法弄清楚如何从指令范围传递用户(通知它警告未定义)。
这是一个示例指令(从我的实际应用程序中大大简化):
var app = angular.module('plunker', []);
app.controller("AppCtrl", function($scope) {
$scope.click = function(user) {
alert(user)
}
$scope.users = [{
name: 'John',
id: 1
}, {
name: 'anonymous'
}];
});
app.directive("myDir", function($compile) {
return {
scope: {
user: '=',
click: '&'
},
compile: function(el) {
el.removeAttr('my-dir');
el.attr('ng-click', 'click(user)')
var fn = $compile(el);
return function(scope, el){
fn(scope);
};
}
};
});
这是html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.2.x" src="http://code.angularjs.org/1.2.12/angular.js" data-semver="1.2.12"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="AppCtrl">
<a my-dir user="{name: 'Works', id: 0}" click="click()">This works</a>
<a my-dir user="user" click="click()" ng-repeat="user in users"><br>{{user.name}}</a>
</div>
</body>
</html>
谢谢!
答案 0 :(得分:3)
当然,对于这样的事情,编译功能是不需要的。实际上,从1.2开始,编译函数几乎从不需要。我已经看到MIGHT需要编译功能的唯一指令是ng-repeat指令本身,我甚至不相信这是真的。
要记住的一件重要事情是,当一个函数传递给一个指令来被调用时,当在html中指定了该函数时,这就是参数绑定时的情况。所以给出了以下控制器(注意我重命名了被调用的函数更明确)
app.controller("AppCtrl", function($scope) {
$scope.raiseNotification = function(user) {
alert(user.name)
}
....
以及以下指令:
app.directive("myDir", function($compile) {
return {
restrict: 'E',
scope: {
user: '=',
click: '&'
},
template: '<a ng-click="click()" ><br>{{user.name}}</a>'
};
});
如果你想调用这个方法,那么下面的HTML就是你想要的
<div ng-repeat="user in users">
<my-dir user="user" click="raiseNotification(user)" ></my-dir>
</div>
调用click时(请注意,指令模板中的click()没有自己的参数。因为模板中的click()实际上是调用raiseNotification的包装器(用户)即
function click() {
raiseNotification(user);
}
如果您希望从指令中的某个位置调用click函数并覆盖用户绑定的内容,那么您可以这样做:
click({user:myOtherUser})
这将覆盖&#34;用户&#34;参数绑定到。这是一个非常优秀的案例。
Here's对像素比特代码的调整,其中包含未在指令模板中指定的用户参数的修复程序。
另外,只是为了好玩,here's另一个版本更接近你正在做的事情但使用链接功能。它不像以前给出的代码那样简洁或优雅,但如果你需要对节点上的事件做更具体的事情,可以使用链接功能进行更多控制。
答案 1 :(得分:1)
当您尝试重新编译/重新链接已编译或正在编译的指令时,可能会导致此问题。当你试图重新编译/重新链接一个指令时,这是一个重要的红旗,你正在做一些你不应该做的事情。
而不是与框架作斗争,并让它做一些它不应该做的模糊的事情,尝试在框架内工作,你会发现完成这些任务要容易得多。做。
首先,这是一个有效的demo。
提示1:如果您要重新编译指令 - 请不要。这有很多陷阱,比它的价值更麻烦。重新组织您的HTML,这样您就不必:
<div ng-controller="AppCtrl">
<div ng-init="user = {name: 'Works', id: 0}">
<my-dir user="user" click="click(user)"></my-dir>
</div>
<div ng-repeat="user in users">
<my-dir user="user" click="click(user)" ></my-dir>
</div>
</div>
提示2 :如果您正在使用隔离范围,请在指令中使用模板。模板可以利用隔离范围,并有助于使您的指令更加模块化和可重复使用。
app.directive("myDir", function($compile) {
return {
restrict: 'E',
scope: {
user: '=',
click: '&'
},
template: '<a ng-click="click(user)" ><br>{{user.name}}</a>'
};
});
提示3 :不要使用&#39;替换&#39;,因为它已被弃用。相反,如果必须,请使用元素指令。
Angular会对您应遵循的HTML格式强加一些约定,这可能意味着您的HTML中有一些您不希望在最终HTML中使用的额外标记。但我了解到,考虑到生产率的提高,这是一个很小的代价。