Angularjs 动态添加控制器 [英] Angularjs add controller dynamically

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

问题描述

这个问题好像已经问过几次了,但没有正确答案.

我的情况:我正在使用 ajax 加载一个模板(带有 html 和脚本)init 到 div(由于某种原因不使用角度路由寺庙).

index.html(主)

<html ng-app="app" ng-controller="AppCtrl"><头><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>网页</title><script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script><身体><div class="container body-content"><div class="dynamic-content" ><!-- 在此处加载内容-->

<button ng-click="loadTemplate()">加载模板</button>

<脚本>angular.module('app', []).controller('AppCtrl', function ($scope) {$scope.someData = {};$scope.loadTemplate = function() {....//AJAX获取templet.html//并将其加载到 .dynamic-content//然后应用范围();}});</html>

template.html(模板)

<h2>关于</h2><h3>{{total}}</h3><p>测试总数</p><button ng-click="update()">更新</button>

<脚本>console.log('开始')angular.module('app').controller('TempCtrl', function ($scope) {$scope.total = 0;console.log('里面')$scope.update = 函数 () {$scope.total += 1;};});console.log('end')

当我单击按钮 Load Template 时,它会将 template.html 文件加载到容器中,但出现错误

<块引用>

错误:[ng:areq] 参数TempCtrl"不是函数, 未定义

虽然它被添加到应用控制器中.

如何动态添加控制器并使其与动态 html 节点一起工作

此处演示 https://plnkr.co/edit/EAa9Md36hDzpQ1BgIQKg?p=预览

解决方案

这个博客描述了如何摆弄 angular 以强制它在引导后加载额外的控制器:

http://www.bennadel.com/blog/2553-loading-angularjs-components-after-your-application-has-been-bootstrapped.htm

当然,这是完全不受支持的,并且随时可能因 angular 的变化而中断.

但是,这是使用此方法的代码的更新版本:

var app = angular.module('app', [])应用程序配置(功能($controllerProvider,$provide,$compileProvider){//由于组件的速记"方法//定义不再有效,我们可以//覆盖它们以使用提供程序进行后期处理//引导加载.console.log("配置方法执行.");//让我们保留旧的引用.app._controller = app.controller;app._service = app.service;app._factory = app.factory;app._value = app.value;app._directive = app.directive;app.controller = 函数(名称,构造函数){console.log("控制器...");控制台日志(名称);控制台.目录(构造函数);$controllerProvider.register(name, 构造函数);返回(这个);};//基于提供者的服务.app.service = 函数(名称,构造函数){$provide.service(name, 构造函数);返回(这个);};//基于提供者的工厂.app.factory = 函数(名称,工厂){$provide.factory(name, factory);返回(这个);};//基于提供者的值.app.value = 函数(名称,值){$provide.value(name, value);返回(这个);};//基于提供者的指令.app.directive = 函数(名称,工厂){$compileProvider.directive(name, factory);返回(这个);};});app.controller('AppCtrl', function($scope, $http, $compile) {$scope.someData = {};$scope.loadTemplate = function() {$http.get("template.html").then(function(r) {//加载 html,包括将要执行的脚本$(".dynamic-content").html(数据);//将加载的 html 编译为实际模板并将其放回原来的位置$(".dynamic-content").html($compile($(".dynamic-content").html())($scope));})}});

请注意,我使用 jQuery 将 HTML 放入 DOM,导致脚本执行,然后从 DOM 中取出 HTML 以便进行编译,之后我再次将其放回 DOM.

另外,你的 template.html 中有一个未定义的变量,所以我将它更新为如下所示:

<div ng-controller="TempCtrl"><h2>关于</h2><h3>{{total}}</h3><p>测试总数</p><button ng-click="update()">更新</button>

这是一个有效的 plunk:http://plnkr.co/edit/cB5N05

It looks like this questions already asked few times but there is no correct answer to it.

my case: i'm loading a template (with html and script) init to div using ajax (not using angular routing temple for some reason).

index.html (main)

<!DOCTYPE html>
<html ng-app="app" ng-controller="AppCtrl">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Web</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    </head>
    <body>
        <div class="container body-content">
            <div class="dynamic-content" >
                <!-- Loading content Here -->
            </div>
            <button ng-click="loadTemplate()">Load Template</button>
        </div>

        <script>
            angular.module('app', [])
            .controller('AppCtrl', function ($scope) {
                $scope.someData = {};
                $scope.loadTemplate = function() {
                    ....
                    //AJAX to get the templet.html
                    //and load it into .dynamic-content
                    //then applying scope();                  
                }
            });
        </script>
    </body>
</html>

template.html (template)

<div ng-controller="TempCtrl">
    <h2>About</h2>
    <h3>{{total}}</h3>
    <p>Testing the total</p>
    <button ng-click="update()">Update</button>
</div>

<script>
    console.log('begin')
    angular.module('app')
    .controller('TempCtrl', function ($scope) {
        $scope.total = 0;
        console.log('inside')
        $scope.update = function () {
            $scope.total += 1;
        };
    });
    console.log('end')
</script>

when i click the button Load Template it loads the template.html file in to container but i'm getting error

Error: [ng:areq] Argument 'TempCtrl' is not a function, got undefined

though its being added to app controllers.

How can i add controllers dynamically and get it work with dynamic html nodes

DEMO HERE https://plnkr.co/edit/EAa9Md36hDzpQ1BgIQKg?p=preview

解决方案

This blog describes how to fiddle with angular to force it to load additional controllers after it has been bootstrapped:

http://www.bennadel.com/blog/2553-loading-angularjs-components-after-your-application-has-been-bootstrapped.htm

Of course, this is completely unsupported, and could be broken by changes to angular at any time.

But, here is an updated version of your code using this method:

var app = angular.module('app', [])
app.config(
  function($controllerProvider, $provide, $compileProvider) {
    // Since the "shorthand" methods for component
    // definitions are no longer valid, we can just
    // override them to use the providers for post-
    // bootstrap loading.
    console.log("Config method executed.");
    // Let's keep the older references.
    app._controller = app.controller;
    app._service = app.service;
    app._factory = app.factory;
    app._value = app.value;
    app._directive = app.directive;
    app.controller = function(name, constructor) {
      console.log("controller...");
      console.log(name);
      console.dir(constructor);
      $controllerProvider.register(name, constructor);
      return (this);
    };
    // Provider-based service.
    app.service = function(name, constructor) {
      $provide.service(name, constructor);
      return (this);
    };
    // Provider-based factory.
    app.factory = function(name, factory) {
      $provide.factory(name, factory);
      return (this);
    };
    // Provider-based value.
    app.value = function(name, value) {
      $provide.value(name, value);
      return (this);
    };
    // Provider-based directive.
    app.directive = function(name, factory) {
      $compileProvider.directive(name, factory);
      return (this);
    };
  });
app.controller('AppCtrl', function($scope, $http, $compile) {
  $scope.someData = {};
  $scope.loadTemplate = function() {
    $http.get("template.html")
      .then(function(r) {
        // load in the html, including the script, which will be executed
        $(".dynamic-content").html(
          r.data
        );
        // compile the loaded html into an actual template and put it back where it was
        $(".dynamic-content").html($compile($(".dynamic-content").html())($scope));
      })
  }
});

Note that I used jQuery to place the HTML into the DOM, causing the script to execute, then to grab the HTML back out of the DOM so it could be compiled, after which I placed it back in the DOM again.

Also, there is an undefined variable in your template.html, so I updated it to look like this:

<script>
    console.log('begin')
    angular.module('app')
    .controller('TempCtrl', function ($scope) {
        $scope.total = 0;
        console.log('inside')
        $scope.update = function () {
            $scope.total += 1;
        };
    });
    console.log('end')
</script>

<div ng-controller="TempCtrl">
    <h2>About</h2>
    <h3>{{total}}</h3>
    <p>Testing the total</p>
    <button ng-click="update()">Update</button>
</div>

Here is a working plunk: http://plnkr.co/edit/cB5N05

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

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