如何将 AngularJS 控制器绑定到动态添加的 HTML? [英] How to bind an AngularJS controller to dynamically added HTML?

查看:28
本文介绍了如何将 AngularJS 控制器绑定到动态添加的 HTML?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于这种情况,我有一个 HTML 页面,其中包含一些 AngularJS 指令、控制器等.

像这样:

<身体><div ng-controller="myCtrl"><ul><li ng-repeat="item in items">{{item.name}}</li></ul>

<div class="placeholder">...这里有新的 HTML...

</html>

请注意,页面上没有 ng-app 指令.我不依赖自动引导,而是使用手动引导方法.

angular.bootstrap(document, ['myApp']);

首先,我创建将引导到文档的模块.然后,当加载动态确定的依赖项列表时,我会附加一些服务、控制器等.一旦一切准备就绪,我就会调用 bootstrap 方法.

这一切正常,直到 AngularJS 之外的 JavaScript 在 ...new HTML here... 位置附加到 DOM.新的 HTML 不是由 AngularJS 处理的.

我的理解是您需要调用 $scope.$apply()$digest() 或其他东西来让 AngularJS 识别新的 HTML.但是,在我的示例中,传入的新 HTML 周围没有控制器.传入的 HTML 可能如下所示:

 

<h2>{{model.title}}</h2>

换句话说,它依赖于应用模块中的不同控制器.

  • 我无法再次调用 angular.bootstrap 方法,因为页面已经绑定.
  • 我无法从控制器内部调用 $scope.$apply,因为整点是控制器代码没有被调用.
  • 我没有看到获取对控制器的引用以重新应用或刷新它的方法.

我已阅读 Ifeanyi Isitor 延迟加载帖子Ben Nadel 帖子,但他们似乎没有解决加载到外面的 HTML现有控制器的上下文.

我不能选择使用 AngularJS 指令来处理 DOM 操作.它是架构的一个单独部分,它使用 ExtJS 作为注入新 DOM 元素的框架.这意味着我不能使用 ngInclude 例如.

看起来我可以只调用 angular.module('myApp').$refresh();.$apply() 但这不是一个选项.我错过了什么?

解决方案

我遇到了同样的问题,这是我想出的:

<div id=ee">第二个控制器的视图应该在这里渲染

并调用 setCnt() 函数将注入并编译 html,并将其链接到第二个控制器:

var app = angular.module('app', []);函数 setCnt() {//注入视图的htmlvar e1 = angular.element(document.getElementById(ee"));e1.html('<div ng-controller="ctl2">我的名字:{{name}}</div>');//编译控制器 2 htmlvar mController = angular.element(document.getElementById(mController"));mController.scope().activateView(e1);}app.controller(mainController", function($scope, $compile) {$scope.name = "这是名称 1";$scope.activateView = function(ele) {$compile(ele.contents())($scope);$scope.$apply();};});app.controller(ctl2",函数($scope){$scope.name = "这是名称 2";});

这里有一个例子来测试这个:https://snippet.run/x4bc

希望这会有所帮助.

For this scenario, I have a page of HTML with some AngularJS directives, controllers, etc.

Something like this:

<html>
<body>
  <div ng-controller="myCtrl">
     <ul><li ng-repeat="item in items">{{item.name}}</li></ul>
  </div>
  <div class="placeholder">
     ...new HTML here...
  </div>
</body>
</html>

Notice that there is no ng-app directive on the page. I am not relying on auto-bootstrapping, but rather I am using the manual bootstrapping method.

angular.bootstrap(document, ['myApp']);

First, I create the module which will be bootstrapped to the document. Then as a dynamically determined list of dependencies are loaded, I attach some services, controllers, etc. Once everything is ready I call the bootstrap method.

This all works fine, until JavaScript outside of AngularJS appends to the DOM at the ...new HTML here... location. The new HTML is not processed by AngularJS.

My understanding is that you need to call $scope.$apply() or $digest() or something to get AngularJS to recognize the new HTML. However, in my example there is no controller around the new HTML coming in. The incoming HTML may look like this:

  <div ng-controller="myOtherCtrl">
     <h2>{{model.title}}</h2>
  </div>

In other words, it is relying on a different controller in the app module.

  • I can't call the angular.bootstrap method again, because the page is already bound.
  • I can't call $scope.$apply from inside the controller because the whole point is that controller code isn't being called.
  • I don't see a way to get a reference to the controller in order to re-apply or refresh it.

I have read the Ifeanyi Isitor lazy loading post and the Ben Nadel post, yet they don't seem to address HTML loaded outside the context of an existing controller.

It isn't an option for me to use AngularJS directives to handle the DOM manipulation. It is a separate part of the architecture which uses ExtJS as the framework for injecting the new DOM elements. This means I can't use ngInclude for example.

It would seem like I could just call angular.module('myApp').$refresh(); or .$apply() but that isn't an option. What am I missing?

解决方案

I've faced the same issue, here's what I came up with :

<div id="mController" ng-controller="mainController">
</div>

<div id="ee">
  2nd controller's view should be rendred here
</div>

and calling setCnt() function will inject and compile the html, and it will be linked to the 2nd controller:

var app = angular.module('app', []);

function setCnt() {
  // Injecting the view's html
  var e1 = angular.element(document.getElementById("ee"));
  e1.html('<div ng-controller="ctl2">my name: {{name}}</div>');
  
  // Compile controller 2 html
  var mController = angular.element(document.getElementById("mController"));
  mController.scope().activateView(e1);
}

app.controller("mainController", function($scope, $compile) {
  $scope.name = "this is name 1";

  $scope.activateView = function(ele) {
    $compile(ele.contents())($scope);
    $scope.$apply();
  };
});

app.controller("ctl2", function($scope) {
  $scope.name = "this is name 2";
});

here's an example to test this : https://snippet.run/x4bc

hope this helps.

这篇关于如何将 AngularJS 控制器绑定到动态添加的 HTML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆