注入动态html似乎无法编译 [英] injecting dynamic html doesn't seem to compile

查看:102
本文介绍了注入动态html似乎无法编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决与AngularJS有关的一个主要问题,该问题涉及使用包含ng-controller的动态添加的html.

让我们说我想向DOM中添加一个ng-controller的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>

将按预期输出以下内容:

{"test1":一个","test2":两个"}

但是,现在让我们说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!
{{demo}}

到目前为止,这是有道理的; angular已经在DOM中完成了自己的工作,并完成了工作.尚未告知要添加新的东西. 因此,如果我们看一下AngularJS手册,就在此页面底部,我们了解了如何告诉我们我们刚刚添加了一些内容:

有时您想访问当前的注射器 从Angular外部运行Angular应用程序.也许,你想注入 并在应用程序启动后编译一些标记. 您可以使用添加到JQuery/jqLit​​e的多余的jector()来执行此操作 元素.参见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!
{{demo}}

您能指出我在做错什么吗,因为无所不用其极,阅读手册也无济于事,因为一切似乎都表明我的代码正确!

解决方案

通过 Angular ng-click调用的函数调用时,您的代码照常工作./p>

由于您似乎真的想避免使用Angular,因此希望使用传统的onclick事件处理程序,因此需要将更改包装到对$scope.$apply()的调用中:

which outputs the following, as expected:

{"test1":"one","test2":"two"}

However, now lets say that the div actually has to be loaded dynamically, perhaps when a user presses a button. In this case, I'd replace the tag in the above example with the following:

<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>

which outputs the following when I click the button:

Click to add Div!
{{demo}}

So far, this makes sense; angular has already worked its way through the DOM, done it's thing, and finished. It's not been told about new stuff being added. So, if we look at the AngularJS manual, right at the bottom of this page, we find out how to tell it we've just added some stuff:

Sometimes you want to get access to the injector of a currently running Angular app from outside Angular. Perhaps, you want to inject and compile some markup after the application has been bootstrapped. You can do this using the extra injector() added to JQuery/jqLite elements. See angular.element.

This is fairly rare but could be the case if a third party library is injecting the markup.

In the following example a new block of HTML containing a ng-controller directive is added to the end of the document body by JQuery. We then compile and link it into the current AngularJS scope. var $div = $('{{content.label}}'); $(document.body).append($div);

angular.element(document).injector().invoke(function($compile) {
  var scope = angular.element($div).scope();
  $compile($div)(scope);
});


So... with this in mind, we update addDiv() function in our example as follows:

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);
    });
}

And now when we run it, we should be golden right?
Nope.. we still get the following:

Click to add Div!
{{demo}}

Can you point out what I'm doing wrong, as no end of googling and reading the manual is helping, as everything seems to suggest I've got the code right!

解决方案

Your code works as is when invoked from a function called from an Angular ng-click.

Since you seem to really want to avoid using Angular, and thus want a traditional onclick event handler, you need to wrap the changes into a call to $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);
    });
});

这篇关于注入动态html似乎无法编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆