在下面的代码中,我试图在编译阶段添加一个按钮,并从范围分配ng-click到一个方法。 在链接阶段,通过调试我发现“compiledEle”包含按钮,然后ng-click也不会调用范围方法。
angular.module("app", [])
.controller("ctrl1", function($scope){
$scope.myModelObj = {
name: 'Ratnesh',
value: 100
};
})
.directive("dirOne",function($compile){
return {
restrict: 'E',
scope: {
myModel : "="
},
compile: function(ele){
ele.append("<button ng-click=\"showAlert()\">click ME</button>")
return {
post: function($scope, compiledEle){
$scope.showAlert = function(){
alert("The button is clicked");
};
}
};
}
};
});
在编译阶段,范围方法没有绑定到按钮的原因可能是什么原因,但如果我在模板/ templateUrl中按下,则可以绑定相同的内容。如果在链接阶段我们包含一行:
,该方法也会被绑定$编译(compiledEle.contents())($范围);)
如果不是在链接阶段添加“$ scope.showAlert”,它将被绑定到方法,我们已经在控制器中有了方法!!!
.controller("ctrl1", function($scope){
$scope.myModelObj = {
name: 'Ratnesh',
value: 100
};
$scope.showAlert = function(){
alert("The button is clicked");
};
})
编译方法是做DOM操作,链接阶段是将编译好的html链接到范围。所以我们可以在编译期间向DOM添加新元素,在链接阶段添加新范围方法,那么我的期望在哪里出错?
答案 0 :(得分:3)
问题是你的编译函数在编译时还无法访问元素实例的范围。
您希望app.directive("fromCompile", function($compile) {
return {
restrict: 'E',
scope: {},
compile: function(tElement) {
// When AngularJS compiles the template element, it does not have
// access yet to the scope of the iElement, because the iElement does
// not exist yet.
// You want ng-click to execute a method of the iElement scope
// which does not exist here yet because you are modifying the
// template element, not the instance element.
// This will not give you the effect you are looking for because it
// will execute the function in a scope higher up the scope hierarchy.
tElement.append('<button ng-click=\"showAlert()\">Using compile: click me (this will not work correctly)</button>');
return {
post: function(scope, iElem, iAttrs) {
scope.showAlert = function() {
alert("This button was added using compile");
};
}
};
}
};
});
执行实例范围的方法,该方法在编译模板时尚不可用。
我在代码中添加了注释来说明会发生什么:
app.directive("fromTemplate", function($compile) {
return {
restrict: 'E',
scope: {},
template: "<button ng-click=\"showAlert()\">Using template: click me (this will work)</button>",
link: function(scope, iElem, iAttrs) {
scope.showAlert = function() {
alert("This button was added using template");
};
}
};
});
要解决此问题,您可以使用模板让AngularJS自动为您编译模板:
app.directive("fromLink", function($compile) {
return {
restrict: 'E',
scope: {},
link: function(scope, iElem, iAttrs) {
var linkFn = $compile("<button ng-click=\"showAlert()\">Using link: click me (this will work)</button>");
var button = linkFn(scope);
iElem.append(button);
scope.showAlert = function() {
alert("The button was added using $compile in link function");
};
}
};
});
或者在元素实例的链接函数中自己手动编译模板(因为你可以在那里访问正确的范围):
{{1}}
我创建了一个包含所有代码和工作版本right here的Plunk。
希望有所帮助!