"Scope doesn't get associated with new element added in compile phase" 的意思是:作用域不会关联在编译阶段添加的新元素上。
"Scope doesn't get associated with new element added in compile phase" 的意思是:作用域不会关联在编译阶段添加的新元素上。
在下面的代码中,我试图在编译阶段添加一个按钮,并将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("") return { post: function($scope, compiledEle){ $scope.showAlert = function(){ alert("The button is clicked"); }; } }; } }; });
为什么作用域方法不会绑定到编译阶段添加的按钮,但是如果在模板/模板URL中添加按钮,则可以绑定相同的内容。如果在连接阶段包含以下行,则该方法也将绑定:
$compile(compiledEle.contents())($scope);)
如果不是在连接阶段添加“$scope.showAlert”,而是在控制器中已经有该方法,则它将绑定到该方法!
.controller("ctrl1", function($scope){ $scope.myModelObj = { name: 'Ratnesh', value: 100 }; $scope.showAlert = function(){ alert("The button is clicked"); }; })
编译方法用于执行DOM操作,连接阶段用于将已编译的HTML链接到作用域。因此,我们可以在编译期间向DOM添加新元素,并在连接阶段添加新的作用域方法,那么我的期望在哪里出了差错?
admin 更改状态以发布 2023年5月21日
问题在于,在编译时,您的编译函数没有访问元素实例作用域的权限。您希望ng-click执行实例作用域的方法,但此时模板还未编译。\n\n我已经添加了注释来说明发生了什么:\n\n
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(''); return { post: function(scope, iElem, iAttrs) { scope.showAlert = function() { alert("This button was added using compile"); }; } }; } }; });
\n\n为解决此问题,您可以使用模板,让AngularJS自动为您编译模板:\n\n
app.directive("fromTemplate", function($compile) { return { restrict: 'E', scope: {}, template: "", link: function(scope, iElem, iAttrs) { scope.showAlert = function() { alert("This button was added using template"); }; } }; });
\n\n或者在元素实例的链接函数中手动编译模板(因为您可以在那里访问正确的作用域):\n\n
app.directive("fromLink", function($compile) { return { restrict: 'E', scope: {}, link: function(scope, iElem, iAttrs) { var linkFn = $compile(""); var button = linkFn(scope); iElem.append(button); scope.showAlert = function() { alert("The button was added using $compile in link function"); }; } }; });
\n\n我创建了一个带有所有代码和工作版本的Plunk,在这里。\n\n希望这可以帮到您!