Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >按需加载 AngularJS 的 Controller

按需加载 AngularJS 的 Controller

作者头像
beginor
发布于 2020-08-10 06:44:22
发布于 2020-08-10 06:44:22
1.3K00
代码可运行
举报
运行总次数:0
代码可运行

按需加载 AngularJS 的 Controller

多视图应用

AngularJS 通过路由支持多视图应用, 可以根据路由动态加载所需的视图, 在 AngularJS 的文档中有详细的介绍, 网上也有不少教程, 就不用介绍了!

随着视图的不断增加, js文件 会越来越多, 而 AngularJS 默认需要把全部的 js 都一次性加载, 使用起来非常不便, 因此按需加载模块的需求会越来越强, 不过, AngularJS 并没有实现按需加载。

异步加载

关于异步加载, AngularJS 的开发指南中有这样一段话

Modules are a way of managing $injector configuration, and have nothing to do with loading of scripts into a VM. There are existing projects which deal with script loading, which may be used with Angular. Because modules do nothing at load time they can be loaded into the VM in any order and thus script loaders can take advantage of this property and parallelize the loading process.

这段话的大意是说 AngularJS 的模块只关注依赖注入,不关注脚本是怎么加载的。 目前已经有项目来处理脚本加载, 可以和 AngularJS 一起使用。 模块在加载的过程中什么都没做, 可以按照任意顺序加载, 因此脚本加载器可以使用这个特性进行并发加载。

AngularJS 在 $routeProvider文档中, when 方法的 route 参数有这样一个属性:

  • resolve - {Object.<string, function>=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated.

routeresolve 参数是一个可选依赖的 map 对象, 如果这个对象有成员是 promise 对象, 路由就会等待 promise 对象完成再初始化 controller 。

可以通过这一点, 来刻意创建一个 promise 对象加载需要的模块, 比如下面的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$routeProvider.when('/myView', {
    controller: 'MyController',
    templateUrl: '/views/myView.html',
    resolve: {
        deps: function($q, $rootScope) {
            var defered = $q.defer();
            require(dependencies, function() {
                $rootScope.$apply(function() {
                    defered.resolve();
                });
            });
            return defered.promise;
        }
    }
});

为此, 可以单独写一个 loader.js 来生成 promise 对象, 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
define([], function() {
    return function(dependencies) {
        // 返回路由的 resolve 定义, 
        var definition = {
            // resolver 是一个函数, 返回一个 promise 对象;
            resolver: ['$q', '$rootScope', function($q, $rootScope) {
                // 创建一个延迟执行的 promise 对象
                var defered = $q.defer();
                // 使用 requirejs 的 require 方法加载的脚本
                require(dependencies, function() {
                    $rootScope.$apply(function() {
                        // 加载完脚本之后, 完成 promise 对象;
                        defered.resolve();
                    });
                });
                返回延迟执行的 promise 对象, route 会等待 promise 对象完成
                return defered.promise;
            }]
        };
        return definition;
    }
});

将应用的路由单独放在一个 route.js 文件中进行定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
define([], function () {
    return {
        defaultRoute: '/welcome',
        routes: {
            '/welcome': {
                templateUrl: 'components/welcome/welcomeView.html',
                controller: 'WelcomeController',
                dependencies: ['components/welcome/welcomeController']
            },
            '/dialogs': {
                templateUrl: 'components/dialogs/dialogsView.html',
                controller: 'DialogsController',
                dependencies: ['components/dialogs/dialogsController']
            },
            '/list': {
                templateUrl: 'components/list/listView.html',
                controller: 'ListController',
                dependencies: ['components/list/listController']
            },
            '/user': {
                templateUrl: 'components/user/userView.html',
                controller: 'UserController',
                dependencies: ['components/user/userController']
            },
            '/help': {
                templateUrl: 'components/help/helpView.html',
                controller: 'HelpController',
                dependencies: ['components/help/helpController']
            }
        }
    };
});

$routeProvider 根据上面的定义进行初始化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (routeConfig.routes != undefined) {
    angular.forEach(routeConfig.routes, function(route, path) {
        $routeProvider.when(path, {
            templateUrl: route.templateUrl,
            controller: route.controller,
            // 设置每个路由的 resolve , 使用 requirejs 加载 controller 脚本
            resolve: loader(route.dependencies)
        });
    });
}

if (routeConfig.defaultRoute != undefined) {
    $routeProvider.otherwise({ redirectTo: routeConfig.defaultRoute });
}

手工注册 Controller

对于动态加载下来的 Controller 需要手工注册, 这就需要调用 $controllerProviderregister 方法, 为了方便使用, 可以定义一个全局的 app 对象, 将 AngularJS 的注册 controller 、 directive 、 filter 、 factory 、 service 方法都暴露出来, 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
define(['app.routes', 'app.loader', 'angular', 'angular-route'], function (config, loader) {
    'use strict';

    var app = angular.module('app', ['ngRoute', 'ngResource', 'ui.bootstrap']);
    app.config(configure);

    configure.$inject = ['$routeProvider', '$locationProvider', '$controllerProvider', '$compileProvider', '$filterProvider', '$provide'];

    return app;

    function configure($routeProvider, $locationProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
        app.registerController = $controllerProvider.register;
        app.registerDirective = $compileProvider.directive;
        app.registerFilter = $filterProvider.register;
        app.registerFactory = $provide.factory;
        app.registerService = $provide.service;
    }
});

有了这个 app 之后, 要做动态加载的 controller 就可以这样写了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 将 controller 定义为一个 AMD 模块, 依赖上面的 app
define(['app'], function(app) {
    'use strict';
    // 调用 app 暴露的 registerController 方法注册 controller
    app.registerController('HelpController', HelpController);
    // 定义 controller 的注入对象;
    HelpController.$inject = ['$scope'];
    // controller 具体实现
    function HelpController($scope) {
        $scope.greeting = 'Help Info';
    }
});

点击这里查看完整的例子 https://github.com/beginor/html-app-demo/tree/master/www

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何在 ASP.NET MVC 中集成 AngularJS(3)
今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容。 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表:一个运行在调试模式的应用程序下和一个运行在发布模式的应用程序下。在调试模式下,JavaScript 文件在未使用压缩功能的情况下会被下载。如果想要调试并在 JavaScript 控制器中设置断点,这是必须的。事实上,路由表的产生版本也出现了一些挑战,由于产生路由代码使用的是 JavaScript 捆绑,但是在
葡萄城控件
2018/01/10
1.9K0
如何在 ASP.NET MVC 中集成 AngularJS(3)
AngularJS 路由--设置对象
$routeProvider.when 函数的第一个参数是 URL 或者 URL 正则规则,第二个参数为路由配置对象。
陈不成i
2021/07/26
9870
AngularJs ng-route路由详解
本篇基于ng-route来讲下angular中的路由,路由功能主要是 $routeProvider服务 与 ng-view 实现。 ng-view的实现原理,是根据路由的切换,动态编译html模板——$compile(html)(scope)。 更多内容参考:Angularjs总结 前提 首先需要在页面引入angular和angular-route,注意要在angular-route之前引入angular <script src="../../bower_components/angular/an
用户1154259
2018/01/17
2K0
【AngularJS】 # AngularJS入门
ng-app 指令定义一个 AngularJS 应用程序。 若不声明,将直接显示表达式。
全栈程序员站长
2022/09/15
23.6K0
【AngularJS】 # AngularJS入门
浅谈HTML5单页面架构(一)——requirejs + angular + angular-route
心血来潮,打算结合实际开发的经验,浅谈一下HTML5单页面App或网页的架构。 众所周知,现在移动Webapp越来越多,例如天猫、京东、国美这些都是很好的例子。而在Webapp中,又要数单页面架构体验最好,更像原生app。简单来说,单页面App不需要频繁切换网页,可以局部刷新,整个加载流畅度会好很多。 废话就不多说了,直接到正题吧,浅谈一下我自己理解的几种单页面架构: 1、requirejs+angular+angular-route(+zepto)   最后这个zepto可有可无,主要是给团队中实在用不爽
用户1258909
2018/07/03
3.4K0
AngularJS中的按需加载ocLazyLoad
初学者,有不足的地方希望各位指出 一、前言     ocLoayLoad是AngularJS的模块按需加载器。一般在小型项目里,首次加载页面就下载好所有的资源没有什么大问题。但是当我们的网站渐渐庞大起来,这样子的加载策略让网速初始化速度变得越来越慢,用户体验不好。二来,分模块加载易于团队协作,减低代码冲突。   二、按需加载的对象 各个Controller模块、Directive模块、Server模块、template模板,其实这些都是一些 .js文件或者 .html文件 。     三 、按需加载的场
庞小明
2018/03/07
1.7K0
在AngularJS应用中实现认证授权
在AngularJS应用中实现认证授权 在每一个严肃的应用中,认证和授权都是非常重要的一个部分。单页应用也不例外。应用并不会将所有的数据和功能都 暴露给所有的用户。用户需要通过认证和授权来查看应用的某个特定部分,或者在应用中进行特定的行为。为了在应用中对用户进行识别,我们需要让用户进行登录。 在用户管理方面,传统的服务器端应用和单页应用的实现方式有所不同,单页应用能够和服务器通信的方式只有AJAX。对于登录和退出来说也是如此。 负责识别用户的服务器端需要暴露出一个认证断电。单页应用将会把用户输入的信息发
庞小明
2018/03/07
2.2K0
在AngularJS应用中实现认证授权
AngularJS 的 API:模块 API、指令 API、服务 API、过滤器 API、路由 API
AngularJS 是一款流行的前端 JavaScript 框架,提供了丰富的 API 接口,用于实现前端应用的各种功能。本文将详细介绍 AngularJS 的 API,包括模块 API、指令 API、服务 API、过滤器 API、路由 API 等内容,帮助开发者充分了解和熟练运用 AngularJS 的各项功能。
网络技术联盟站
2023/07/05
3850
AngularJS 多视图应用中的登录认证
在 AngularJS 的多视图应用中, 一般都有实现登录认证的需求, 最简单的解决方法是结合服务端认证, 做一个单独的登录页面, 登录完成之后再跳转回来, 这种方法当然可取, 不过就破坏了单页面应用 (SPA) 的体验, 追求完美的开发者肯定不会采用这种方法。
beginor
2020/08/10
2.8K0
Angularjs 通过asp.net web api认证登录
Angularjs 通过asp.net web api认证登录 Angularjs利用asp.net mvc提供的asp.net identity,membership实现居于数据库的用户名/密码的认
阿新
2018/04/12
2.2K0
Angularjs 通过asp.net web api认证登录
【Hybrid开发高级系列】AngularJS(一)——基础专题
  一向不喜欢追求刚刚新鲜出炉的事物的我,终于在node js出来一年后开始迈出脚步。
江中散人_Jun
2023/10/16
7680
【Hybrid开发高级系列】AngularJS(一)——基础专题
如何在 ASP.NET MVC 中集成 AngularJS(2)
在如何在 ASP.NET MVC 中集成 AngularJS(1)中,我们介绍了 ASP.NET MVC 捆绑和压缩、应用程序版本自动刷新和工程构建等内容。 下面介绍如何在 ASP.NET MVC 中集成 AngularJS 的第二部分。 ASP.NET 捆绑和压缩 CSS 和 JavaScript 的捆绑与压缩功能是 ASP.NET MVC 最流行和有效的特性之一。捆绑和压缩降低了 HTTP 请求和有效载荷的大小,结果是可以更快和更好的执行 ASP.NET MVC 的网站。有许多可以减少 CSS 和 Ja
葡萄城控件
2018/01/10
8.5K0
前端MVC学习总结(三)——AngularJS服务、路由、内置API、jQueryLite
一、服务 AngularJS功能最基本的组件之一是服务(Service)。服务为你的应用提供基于任务的功能。服务可以被视为重复使用的执行一个或多个相关任务的代码块。 AngularJS服务是单例对象,
张果
2018/01/04
6.4K0
前端MVC学习总结(三)——AngularJS服务、路由、内置API、jQueryLite
基于requirejs和angular搭建spa应用1、常规实现2、引入Requirejs
  接上篇,angular 实战部分,angular比较适合spa项目,这里不借助任何seed和构建工具,直接从零搭建,基本的angular项目结构大致包含如下几个部分:   1)app.js 入口   2)index.html html框架页   3)lib(vendor)第三方类库   4)components 业务组件   5)styles/images 静态资源部分 1、常规实现   创建文件夹demo1,按照上述结构分别创建app.js ,index.html文件,创建lib、components
Jerremy
2018/06/13
1.5K0
【Hybrid开发高级系列】AngularJS(三)——开发实践
http://blog.fens.me/angularjs-yeoman-project/
江中散人_Jun
2023/10/16
3540
【Hybrid开发高级系列】AngularJS(三)——开发实践
【ionic+angularjs】angularjs ui-router路由简介($urlRouter、$state、$stateProvider、ui-sref....)
之前有写过一篇关于Angular自带的路由:ngRoute。今天来说说Angular的第三方路由:ui-router。那么有人就会问:为什么Angular有了自带的路由,我们还需要用ui-router呢?这里简单明了的说明下ngRoute和ui-router的区别吧,其实也没很大的区别,主要的就是ngRoute针对于单视图,而ui-router可用于多视图(这里说的视图是指在页面内我们可控制的,可变化的区域)。比如:
用户5640963
2019/07/26
7.3K0
【ionic+angularjs】angularjs ui-router路由简介($urlRouter、$state、$stateProvider、ui-sref....)
AngularJS快速入门
记得第一次听说AngularJS这项很赞的Web的前端技术,那时还是2014年,年中时我们我的一个大牛兄弟当时去面试时,被问到了是否熟悉该技术,当时他了解和使用的技术比较多。我们询问他面试情况时,他给俺这个菜菜科普了该技术,印象比较深的是该技术支持前端MVC架构,可以完成大部分原有的后台工作,当时就觉得很神奇,但由于自身技术基础比较薄弱,没有太多时间和积累去学习新的技术,因而搁置了。在2016新年初始,正好有一些富余时间,正好学习下这个被称为就是“”两个大括号“”的前端框架(当前已经非常成熟,国内大部分公司
用户1216676
2018/01/24
2.6K0
AngularJS快速入门
如何在 ASP.NET MVC 中集成 AngularJS(1)
介绍 当涉及到计算机软件的开发时,我想运用所有的最新技术。例如,前端使用最新的 JavaScript 技术,服务器端使用最新的基于 REST 的 Web API 服务。另外,还有最新的数据库技术、最新的设计模式和技术。 当选择最新的软件技术时,有几个因素在起作用,其中包括如何将这些技术整合起来。过去两年中,我最喜欢的一项技术就是设计单页面应用(SPA)的 AngularJS。作为一个微软stack开发者,我也是使用 ASP.NET MVC 平台实现 MVC 设计模式和并进行研究的粉丝,包括它的捆绑和压缩功能
葡萄城控件
2018/01/10
7.9K0
如何在 ASP.NET MVC 中集成 AngularJS(1)
Angularjs 初步使用总结
IMWeb前端团队
2017/12/29
1.4K0
Angularjs 初步使用总结
Angular.js学习笔记(三)
1、uppercase,lowercase 大小写转换 {{ "lower cap string" | uppercase }} // 结果:LOWER CAP STRING {{ "TANK is GOOD" | lowercase }} // 结果:tank is good 2、date 格式化 {{1490161945000 | date:"yyyy-MM-dd HH:mm:ss"}} // 2017-03-22 13:52:25 3、number 格式化(保留小数) {{149016.1945000 | number:2}}//保留两位 {{149016.1945000 | number}}//默认为保留3位 4、currency货币格式化 {{ 250 | currency }} // 结果:$250.00 {{ 250 | currency:"RMB ¥ " }} // 结果:RMB ¥ 250.00 5、filter查找 输入过滤器可以通过一个管道字符(|)和一个过滤器添加到指令中,该过滤器后跟一个冒号和一个模型名称。 filter 过滤器从数组中选择一个子集 // 查找name为iphone的行 {{ [{"age": 20,"id": 10,"name": "iphone"}, {"age": 12,"id": 11,"name": "sunm xing"}, {"age": 44,"id": 12,"name": "test abc"} ] | filter:{'name':'iphone'} }} 同时filter可以自定义比较函数。 6、limitTo 截取 {{"1234567890" | limitTo :6}} // 从前面开始截取6位 {{"1234567890" | limitTo :6,6}} // 从第6位开始截取6位 {{"1234567890" | limitTo:-4}} // 从后面开始截取4位 7、orderBy 排序 // 根据id降序排 {{ [{"age": 20,"id": 10,"name": "iphone"}, {"age": 12,"id": 11,"name": "sunm xing"}, {"age": 44,"id": 12,"name": "test abc"} ] | orderBy:'id':true }}
HUC思梦
2020/09/03
8.3K0
推荐阅读
相关推荐
如何在 ASP.NET MVC 中集成 AngularJS(3)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验