AngularJS - 在不改变路由的情况下从AJAX异步加载控制器

时间:2017-01-31 15:58:38

标签: javascript jquery html angularjs ajax

我想在呈现新视图(HTML)的ajax调用上动态加载角度控制器。

这就是我所拥有的:

视图示例。来自AJAX的HTML片段

    <!-- CVS Pharmacy Extracare - Add View -->

<div ng-controller="cvsViewCtrl" class="container-fluid">
  <div class="col-md-8 col-md-offset-2">
    <h3 id="asset-title" class=""></h3>
    <br>
    <p>Member ID</p>
    <input class="input-s1 block-elm transition" type="text" placeholder=""/>
    <br>

    <input class="add-asset-btn btn btn-success block-elm transition" type="button" value="Add Asset!" ng-click="prepareCVS();"/>
  </div>
</div>

与视图相关的单独脚本

App.controller('cvsViewCtrl', ['$scope', '$http', function($scope, $http){
    console.log('cvs view loaded');

    $scope.prepareCVS = function() {
      console.log('admit one');
    }
  }]);

以及加载它们的函数

$scope.setAddAssetView = function(a) {
      console.log(a);

      if($scope.currentAddView == a) {
        console.log('view already set');
        return;
      }

      $scope.currentAddView = a;

      $('#main-panel').html('');
      $http({
        method: 'POST',
        url: '/action/setaddassetview',
        headers: {
          'Content-Type': 'application/json',
        },
        data: {
          asset: a,
        }
      }).then(function(resp){
        // Success Callback
        // console.log(resp);
        var index = resp.data.view.indexOf('<s');
        var script = resp.data.view.slice(index);
        var html = resp.data.view.replace(script, '');

        $('#main-panel').html( html );
        $('#asset-title').text(a.name);

        var indexTwo = a.view.indexOf('/add');
        var scriptLink = insertString(a.view, indexTwo, '/scripts').replace('.html', '.js').replace('.', '');
        console.log( scriptLink );
        window.asset = a;

        $.getScript(scriptLink, function(data, textStatus, jqxhr){
          console.log('loaded...');
        })

      },
      function(resp){
        // Error Callback
        console.log(resp);
      });
    }

当$ .getScript运行时,脚本会成功加载,但不会初始化控制器。我甚至尝试过:

var s = document.createElement('script');
s.type = 'text/javascript';
s.src = scriptLink;
s.innerHTML = null;
s.id = 'widget';

document.getElementById('switch-script').innerHTML = '';
document.getElementById('switch-script').appendChild( s );

这会使用正确的链接附加脚本,但仍然无法初始化。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

在您的应用中进行此更改,并确保在使用ng-controller渲染的html之前加载控制器文件。

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

App.config(["$controllerProvider", function($controllerProvider) {

    App.register = {
        controller: $controllerProvider.register,
    }

}]);

App.register.controller('cvsViewCtrl', ['$scope', '$http', function($scope, $http){
    console.log('cvs view loaded');

    $scope.prepareCVS = function() {
      console.log('admit one');
    }
}]);

答案 1 :(得分:0)

这实际上不是处理事情的正确方法。

如果使用ui-router进行路由,则可以在resolve函数中加载控制器。一个很好的服务是ocLazyLoad

可以这样做:

var app = angular.module('myApp', [
    'ui.router',
    'oc.lazyLoad',
]);

angular.module('myApp').config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/login');
    $stateProvider
        .state('main', {
            url: '/main',
            templateUrl: 'app/views/main.view.html',
            controller: 'mainCtrl',
            resolve: {
                loadCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
                    return $ocLazyLoad.load('app/ctrls/main.ctrl.js');
                }],
            }
        })
        .state('second', {
            url: '/second',
            templateUrl: 'app/views/second.view.html',
            controller: 'secondCtrl',
            resolve: {
                loadCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
                    return $ocLazyLoad.load('app/ctrls/controller_TWO.ctrl.js');
                }],
            }
        })

});

当您从一个路线更改为另一个路线时,将在加载html之前触发解决,并且控制器将正确注册。

相关问题