2015-10-19 30 views
4

我试图解决我使用动态添加的html包含ng-controller的angularJS遇到的一个主要问题。注入动态html似乎并没有编译

可以说我想添加一个div到DOM,它是一个ng-controller,它将数据绑定到显示器上。

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

,输出,当我按一下按钮下面:

点击添加事业部!
{{Demo}}

到目前为止,这是有道理的; angular已经通过DOM工作,完成了它的事情,并完成了。它没有被告知添加新的东西。 所以,如果我们看一下AngularJS手册,对在this page底部,我们找出如何告诉它我们只是增加了一些东西:

有时候你想访问的注射器目前 从Angular外部运行Angular应用程序。也许,你想注入 并在应用程序被引导后编译一些标记。 您可以使用添加到JQuery/jqLit​​e 元素的额外注入器()来执行此操作。请参阅angular.element。

这是相当罕见的,但如果第三方库是注入标记的 可能是这种情况。

在下面的例子含有 纳克控制器指令HTML的一个新的块由 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!
{{演示}}

sad panda is sad

你能指出我在做什么错,因为没有谷歌搜索和阅读手册帮助的结束,因为一切都似乎在暗示我有代码正确!

+4

你所有的问题都来自于这样的事实你正在尝试像使用jQuery一样使用AngularJS。您不应该使用AngularJS动态生成或加载HTML。您应该将数据加载为JSON。根据数据包含的内容,使用ng-show,ng-if和其他指令的静态模板应显示/隐藏页面的各个部分。在页面之间导航应该使用路由器完成。 –

+2

在AngularJS应用程序中,addDiv()函数不应添加div。它应该向存储在该范围中的数组添加一个元素。显示此数组的所有元素的ng-repeat指令将检测新元素,并相应地刷新视图。 –

+0

我明白你在说什么,但这并不能真正帮助我,因为我不能真正重新设计我们的整个网络应用程序以便以这种方式使用角度。我正在尝试实现的目标是在一个更大的Web应用程序内的少量动态加载页面中使用角度。如果你看看引用的AngularJS手册,它确实声明这应该是可能的? – Sk93

回答

4

您的代码从通过角度单击调用的函数调用时的工作原样。

因为你似乎真的想避免使用角度,从而希望有一个传统的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); 
    }); 
}); 
+0

这不是我想要避免使用Angular,而是我不能证明几周对现有产品的核心部分进行编码和测试,然后实现将需要半天的功能来写。包含$ rootScope是缺少的关键。简单地补充一下,使一切工作完美。感谢您的答复和帮助。 – Sk93

2

你想编译newDiv,当变量是$ newDiv?

编辑:我认为这是因为你正在使用喷油器并在角度控制器外编译。

我已经安装了一个plunkr http://plnkr.co/edit/utQvgyR7d0jBgx5aEpJa?p=preview来演示这一点。

的例子使用一个控制器上的页面的主体:

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

第二控制器是负责与该内容相关的逻辑。

+0

将此作为澄清问题添加到原始问题中,但不作为答案。 –

+0

@Matt可悲的不是。这只是一个错误的问题,而不是我的代码。更新了这个问题以纠正:) – Sk93