如何绑定AngularJS控制器以动态添加HTML?

时间:2013-12-18 06:59:19

标签: javascript angularjs

对于这种情况,我有一个带有一些AngularJS指令,控制器等的HTML页面。

这样的事情:

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

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

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

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

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

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

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

换句话说,它依赖于app模块中的不同控制器。

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

我已阅读Ifeanyi Isitor lazy loading postBen Nadel post,但它们似乎并未解决在现有控制器上下文之外加载的HTML。

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

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

6 个答案:

答案 0 :(得分:9)

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

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

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

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

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

这是测试此内容的示例:http://refork.com/x4bc

希望这会有所帮助。

答案 1 :(得分:2)

让我们拿一个小模板

 var  template = '<div ng-controller = "someController">';
      template += '<All html you want to add>'; 
      template += '</div>';

现在,如果要添加此模板,您必须执行以下两项操作:

1)通过$controller

实例化您的控制器

2)编译模板。

//this creates a new scope
var $scope = $rootScope.$new();  
//Controller initialize with $scope
$controller('someController',{$scope,$scope});   
var templateEl = angular.element(template);
//Now compile the template with scope $scope
$compile(templateEl)($scope);
angular.element('body').append(templateEL);

答案 2 :(得分:1)

您可能希望使用$compile服务。这就是角度最初的地方。

还有本指南:http://docs.angularjs.org/guide/compiler

答案 3 :(得分:1)

我遇到了同样的问题。 这对我有用:https://docs.angularjs.org/api/ng/function/angular.injector

答案 4 :(得分:0)

我认为ng-include可能对您有所帮助,它会将部分页面加载到元素中,并像编辑网页的任何其他部分一样对其进行编译和处理。

如果此元素是您的网络应用的主视图,并且您想要在其中加载不同的“屏幕”,则根据网址,ng-view可能会派上用场。

答案 5 :(得分:0)

我遵循了这个过程,它对我有用:

// Some variables
var $controllerElement = angular.element('css-selector-to-the-controller-element');
var $appElement = angular.element('css-selector-to-ng-app-element');

// compiling and applying / digesting the scope.
$appElement.injector().invoke(function($compile) {
    var scope = $controllerElement.scope();
    $compile($controllerElement)(scope);
    scope.$apply();
});

参考:here