一尘不染

AngularJS动态添加控制器

angularjs

看来这个问题已经被问过几次了,但是没有正确的答案。

我的情况:我正在使用ajax(出于某种原因不使用角度路由模板)将模板(带有html和脚本)初始化为div。

index.html(主要)

<!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(模板)

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

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

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

尽管已将其添加到应用控制器中。

我如何动态添加控制器并使它与动态HTML节点一起使用

在此处演示
https://plnkr.co/edit/EAa9Md36hDzpQ1BgIQKg?p=preview


阅读 190

收藏
2020-07-04

共1个答案

一尘不染

这个博客描述了如何在启动后用angular来强迫它加载其他控制器:

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

当然,这是完全不受支持的,并且随时可能会因角度更改而被破坏。

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

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

请注意,我使用jQuery将HTML放入DOM中,从而使脚本得以执行,然后将HTML从DOM中抢回,以便可以对其进行编译,然后再将其重新放入DOM中。

另外,您的template.html中有一个未定义的变量,因此我对其进行了更新,如下所示:

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

这是一个工作的小伙伴:http :
//plnkr.co/edit/cB5N05

2020-07-04