AngularJS:延迟加载控制器和内容 [英] AngularJS: lazy loading controllers and content

查看:28
本文介绍了AngularJS:延迟加载控制器和内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个简化的场景中,我有两个文件:index.htm、lazy.htm.

index.htm:

var myApp = angular.module('myApp', []);myApp.controller('embed',function($scope){$scope.embed = '嵌入式控制器';});<div ng-controller="embed">{{embed}}</div><div ng-include="'lazy.htm'"></div>

懒人.htm

myApp.controller('lazy',function($scope){$scope.lazy = '懒惰的控制器';});<div ng-controller="懒惰">{{懒惰的}}

结果是一个错误:Argument 'lazy' is not a function, got undefined"

改用函数

懒人.htm

function lazy($scope) {$scope.lazy = '懒惰的控制器';}<div ng-controller="懒惰">{{懒惰的}}

这在 1.3 beta 14 版本之前有效.在 beta 15 中删除了全局控制器功能:https://github.com/angular/angular.js/issues/8296

那么现在,动态获取lazy.htm 的角度化内容的更好方法是什么?

更新:

在这篇文章中(http://ify.io/lazy-loading-in-angularjs) 我找到了另一个可能的解决方案.$controllerProvider 允许我们在 angular bootstrap 之后注册新的控制器.奇迹般有效.在 v1.3.0-beta.18

中测试

index.htm:

var myApp = angular.module('myApp', []).controller('embed',function($scope){$scope.embed = '嵌入式控制器';}).config(function($controllerProvider) {myApp.cp = $controllerProvider;});<div ng-controller="embed">{{embed}}</div><div ng-include="'lazy.htm'"></div>

懒人.htm

myApp.cp.register('lazy',function($scope){$scope.lazy = '懒惰的控制器';});<div ng-controller="懒惰">{{懒惰的}}

更新 2:

另外两个有效的替代方法是:

懒人.htm

_app = $('[ng-app]').scope();_app.lazy = 函数($scope){$scope.lazy = '懒惰的控制器';};

var $rootScope = $('[ng-app]').injector().get('$rootScope');$rootScope.lazy = 函数($scope){$scope.lazy = '懒惰的控制器';};

但我认为最后两个例子不应该用于生产.

解决方案

你也可以使用 jquery 和 $routeProvider 解析

app.js

/* 模块创建 */var app = angular.module ('app', ['ngRoute']);app.config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider){/*创建更综合的$controllerProvider.register服务形式*/app.registerCtrl = $controllerProvider.register;函数加载脚本(路径){var 结果 = $.Deferred(),script = document.createElement("script");script.async = "异步";script.type = "text/javascript";script.src = 路径;script.onload = script.onreadystatechange = function (_, isAbort) {if (!script.readyState ||/loaded|complete/.test(script.readyState)) {如果(isAbort)结果.拒绝();别的结果.resolve();}};script.onerror = function () { result.reject();};document.querySelector("head").appendChild(script);返回结果.promise();}函数加载器(数组名){返回 {加载:函数($q){var deferred = $q.defer(),map = arrayName.map(function(name) {return loadScript('js/controllers/'+name+".js");});$q.all(map).then(function(r){deferred.resolve();});返回 deferred.promise;}};}$routeProvider.什么时候('/', {templateUrl: 'views/foo.html',解决:装载机(['foo'])}).when('/bar',{templateUrl: 'views/bar.html',控制器:'BarCtrl',解决:装载机(['bar'])}).除此以外({重定向到:document.location.pathname});}]);

/views/foo.html

{{文本}}</节>

js/controllers/foo.js

/*这里我们使用的是$controllerProvider.register的合成版本在视图中注册控制器*/app.registerCtrl('FooCtrl',function($scope){$scope.text = '测试';});

/views/bar.html

{{text2}}</节>

js/controllers/bar.js

app.registerCtrl('BarCtrl',function($scope){$scope.text2 = '测试';});

In this simplified scenario, I have two files: index.htm, lazy.htm.

index.htm:

var myApp = angular.module('myApp', []);
myApp.controller('embed',function($scope){
    $scope.embed = 'Embedded Controller';
});                  
<div ng-controller="embed">{{embed}}</div>    
<div ng-include="'lazy.htm'"></div>

lazy.htm

myApp.controller('lazy',function($scope){
    $scope.lazy = 'Lazy Controller';
});
<div ng-controller="lazy">
    {{lazy}}
</div>

The result is an error: "Argument 'lazy' is not a function, got undefined"

Using a function instead

lazy.htm

function lazy($scope) {
    $scope.lazy = 'Lazy Controller';
}
<div ng-controller="lazy">
    {{lazy}}
</div>

This works until version 1.3 beta 14. In beta 15 was removed the global controller functions: https://github.com/angular/angular.js/issues/8296

So now, what is the better way to get angularized contents of lazy.htm dynamically?

UPDATE:

In this article (http://ify.io/lazy-loading-in-angularjs) I found another possible solution. The $controllerProvider allow us to register new controllers after angular bootstrap. Works like a charm. Tested in v1.3.0-beta.18

index.htm:

var myApp = angular.module('myApp', [])
.controller('embed',function($scope){
    $scope.embed = 'Embedded Controller';
})
.config(function($controllerProvider) {
    myApp.cp = $controllerProvider;
});

<div ng-controller="embed">{{embed}}</div>    
<div ng-include="'lazy.htm'"></div>

lazy.htm

myApp.cp.register('lazy',function($scope){
    $scope.lazy = 'Lazy Controller';
});
<div ng-controller="lazy">
    {{lazy}}
</div>

UPDATE 2:

Two other alternatives that works are:

lazy.htm

_app = $('[ng-app]').scope();    
_app.lazy = function($scope) {
    $scope.lazy = 'Lazy Controller';
};

OR

var $rootScope = $('[ng-app]').injector().get('$rootScope');        
$rootScope.lazy = function($scope) {
    $scope.lazy = 'Lazy Controller';
}; 

But I believe these last two examples should not be used in production.

解决方案

You can also use the jquery with the resolve the $routeProvider

app.js

/* Module Creation */
var app = angular.module ('app', ['ngRoute']);

app.config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider){

/*Creating a more synthesized form of service of $ controllerProvider.register*/
app.registerCtrl = $controllerProvider.register;

function loadScript(path) {
  var result = $.Deferred(),
  script = document.createElement("script");
  script.async = "async";
  script.type = "text/javascript";
  script.src = path;
  script.onload = script.onreadystatechange = function (_, isAbort) {
      if (!script.readyState || /loaded|complete/.test(script.readyState)) {
         if (isAbort)
             result.reject();
         else
            result.resolve();
    }
  };
  script.onerror = function () { result.reject(); };
  document.querySelector("head").appendChild(script);
  return result.promise();
}

function loader(arrayName){

    return {
      load: function($q){
                var deferred = $q.defer(),
                map = arrayName.map(function(name) {
                    return loadScript('js/controllers/'+name+".js");
                });

                $q.all(map).then(function(r){
                    deferred.resolve();
                });

                return deferred.promise;
        }
    };
}

$routeProvider  
    .when('/', {
        templateUrl: 'views/foo.html',
        resolve: loader(['foo'])
    })
    .when('/bar',{
        templateUrl: 'views/bar.html',
        controller: 'BarCtrl',
        resolve: loader(['bar'])
    })
    .otherwise({
        redirectTo: document.location.pathname
    });
}]);

/views/foo.html

<section ng-controller='FooCtrl'>
    {{text}}
</section>

js/controllers/foo.js

/*Here we use the synthesized version of $controllerProvider.register 
to register the controller in view*/
app.registerCtrl('FooCtrl',function($scope){
    $scope.text = 'Test';
});

/views/bar.html

<section>
    {{text2}}
</section>

js/controllers/bar.js

app.registerCtrl('BarCtrl',function($scope){
    $scope.text2 = 'Test';
});

这篇关于AngularJS:延迟加载控制器和内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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