我正在尝试使用angularJS解决我在使用动态添加的包含ng-controller
的html时遇到的一个主要问题。
让我们说我想在一个ng-controller
的DOM中添加一个div,它将绑定数据脱离显示。我可以成功实现如下:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
var demoData = {
'test1': 'one',
'test2': 'two'
};
var myApp = angular.module('myApp', []);
myApp.controller('TestCtrl', function ($scope) {
$scope.demo = demoData;
});
</script>
</head>
<body>
<div ng-controller="TestCtrl">
{{demo}}
</div>
</body>
</html>
按预期输出以下内容:
{ “测试1”: “一个”, “TEST2”: “2”}
但是,现在可以说div实际上必须动态加载,也许当用户按下按钮时。在这种情况下,我将使用以下内容替换上例中的标记:
<body>
<button onclick="addDiv();">Click to add Div!</button>
<script>
function addDiv() {
var newDiv = $('<div ng-controller="TestCtrl">{{demo}}</div>');
$(document.body).append(newDiv);
}
</script>
</body>
单击按钮时输出以下内容:
点击添加Div!
{{演示}}
到目前为止,这是有道理的; angular已经在DOM中完成了它的工作,完成了它。它没有被告知有关新内容的添加。 因此,如果我们查看AngularJS手册,就在this page的底部,我们会发现如何告诉它我们刚刚添加了一些内容:
有时您想要访问当前的注入器 从Angular外部运行Angular应用程序。也许,你想要注射 并在应用程序引导后编译一些标记。 您可以使用添加到JQuery / jqLite的额外注入器()来完成此操作 元素。见angular.element。
这种情况相当罕见,但如果是第三方图书馆则属于这种情况 注入标记。
在以下示例中,包含一个新的HTML块 ng-controller指令被添加到文档正文的末尾 JQuery的。然后我们编译并将其链接到当前的AngularJS范围。 var $ div = $('{{content.label}}'); $(document.body的).append($ DIV);
angular.element(document).injector().invoke(function($compile) { var scope = angular.element($div).scope(); $compile($div)(scope); });
所以......考虑到这一点,我们在示例中更新了addDiv()
函数,如下所示:
function addDiv() {
var $newDiv = $('<div ng-controller="TestCtrl">{{demo}}</div>');
$(document.body).append($newDiv);
angular.element(document).injector().invoke(function ($compile) {
var scope = angular.element($newDiv).scope();
$compile($newDiv)(scope);
});
}
现在当我们运行它时,我们应该是金色的吗? 不,我们仍然得到以下内容:
点击添加Div!
{{演示}}
你能指出我做错了什么,因为谷歌搜索和阅读手册没有结束,因为一切似乎都表明我的代码是正确的!
答案 0 :(得分:6)
您的代码与从 Angular ng-click
调用的函数调用时的工作方式相同。
由于您似乎真的想避免使用Angular,因此需要传统的onclick
事件处理程序,因此您需要将更改包装到对$scope.$apply()
的调用中:http://plnkr.co/edit/EeuXf7fEJsbBmMRRMi5n?p=preview
angular.element(document).injector().invoke(function ($compile, $rootScope) {
$rootScope.$apply(function() {
var scope = angular.element($newDiv).scope();
$compile($newDiv)(scope);
});
});
答案 1 :(得分:3)
当你的变量是$ newDiv?
时,你是否正在尝试编译newDiv?编辑:我认为这是因为您正在使用注入器并在角度控制器之外进行编译。
我在http://plnkr.co/edit/utQvgyR7d0jBgx5aEpJa?p=preview设置了一个plunkr来证明这一点。
该示例在页面正文中使用控制器:
app.controller('InitialController', function ($scope, $injector){
$scope.newBtn = function () {
var $newDiv = $('<div ng-controller="TestCtrl">{{demo}}</div>');
$injector.invoke(function ($compile) {
var div = $compile($newDiv);
var content = div($scope);
$(document.body).append(content);
});
};
});
这负责动态添加内容并使用第二个控制器编译该内容:
app.controller('TestCtrl', function($scope) {
$scope.demo = "This is the div contents";
});
第二个控制器负责与该内容相关的逻辑。