详解angularjs利用ui-route异步加载组件


Posted in Javascript onMay 21, 2017

ui-route相比于angularjs的原生视图路由更好地支持了路由嵌套,状态转移等等。随着视图不断增加,打包的js体积也会越来越大,比如我在应用里面用到了wangeditor里面单独依赖的jquery就300多k。异步加载各个组件就很有必要。在这里我就以ui-route为框架来进行异步加载说明。

首先看一下路由加载文件

angular.module('webtrn-sns').config(['$stateProvider', function ($stateProvider) {
  $stateProvider.state({
      name: 'home.message',
      url: '/message',
      abstract: true,
      templateProvider: ['resources', function (resources) {
        return resources.template
      }],
      controllerProvider: ['resources', (resources)=> {
        return resources.controller
      }],
      onEnter: ['resources', (resources)=>resources.css.use()],
      onExit: ['resources', (resources)=>resources.css.unuse()],
      resolve: {
        resources: ()=> {
          return new Promise(
            resolve => {
              require([], () => {
                resolve({
                  css: require('./css/message_box.css'),
                  template: require('./html/message_box.html'),
                  controller: require('./js/message_box.js')
                })
              })
            }
          );
        }
      }
    }
  ).state({
      name: 'home.message.add_message',
      url: '/add_message?isReply&toUid&title',
      params: {isReply: null, toUid: null, title: null},
      templateProvider: ['resources', function (resources) {
        return resources.template
      }],
      controllerProvider: ['resources', (resources)=> {
        return resources.controller
      }],
      onEnter: ['resources', (resources)=>resources.css.use()],
      onExit: ['resources', (resources)=>resources.css.unuse()],
      resolve: {
        resources: ()=> {
          return new Promise(
            resolve => {
              require(['./js/message.js'], () => {
                resolve({
                  css: require('./css/add_message.css'),
                  template: require('./html/add_message.html'),
                  controller: require('./js/add_message.js')
                })
              })
            }
          );
        }
      }
    }
  )
}])

这个是路由状态的一个声明文件,name,url,param字段的方式不变,关键是看resolve这个部分。根据ui-route的resolve文档,resolve是为了给state或者controller进行自定义注入对象的。

下面是举出文档中关于resolve的例子:

$stateProvider.state('myState', {
   resolve:{
     // Example using function with simple return value.
     // Since it's not a promise, it resolves immediately.
     simpleObj: function(){
      return {value: 'simple!'};
     },
     // Example using function with returned promise.
     // This is the typical use case of resolve.
     // You need to inject any services that you are
     // using, e.g. $http in this example
     promiseObj: function($http){
      // $http returns a promise for the url data
      return $http({method: 'GET', url: '/someUrl'});
     },
     // Another promise example. If you need to do some 
     // processing of the result, use .then, and your 
     // promise is chained in for free. This is another
     // typical use case of resolve.
     promiseObj2: function($http){
      return $http({method: 'GET', url: '/someUrl'})
        .then (function (data) {
          return doSomeStuffFirst(data);
        });
     },    
     // Example using a service by name as string.
     // This would look for a 'translations' service
     // within the module and return it.
     // Note: The service could return a promise and
     // it would work just like the example above
     translations: "translations",
     // Example showing injection of service into
     // resolve function. Service then returns a
     // promise. Tip: Inject $stateParams to get
     // access to url parameters.
     translations2: function(translations, $stateParams){
       // Assume that getLang is a service method
       // that uses $http to fetch some translations.
       // Also assume our url was "/:lang/home".
       return translations.getLang($stateParams.lang);
     },
     // Example showing returning of custom made promise
     greeting: function($q, $timeout){
       var deferred = $q.defer();
       $timeout(function() {
         deferred.resolve('Hello!');
       }, 1000);
       return deferred.promise;
     }
   },
   // The controller waits for every one of the above items to be
   // completely resolved before instantiation. For example, the
   // controller will not instantiate until promiseObj's promise has 
   // been resolved. Then those objects are injected into the controller
   // and available for use. 
   controller: function($scope, simpleObj, promiseObj, promiseObj2, translations, translations2, greeting){
     $scope.simple = simpleObj.value;
     // You can be sure that promiseObj is ready to use!
     $scope.items = promiseObj.data.items;
     $scope.items = promiseObj2.items;
     $scope.title = translations.getLang("english").title;
     $scope.title = translations2.title;
     $scope.greeting = greeting;
   }
  })

我们可以看到resolve的对象是支持Promise的。

再回到我们之前的代码templateProvider和controllerProvider我们注入了resources的模板对象和controller对象,onEnter和onExit注入了css模块。

如果controller中依赖了服务怎么办的?

resolve: {
  resources: ()=> {
    return new Promise(
      resolve => {
        require(['./js/message.js'], () => {
          resolve({
            css: require('./css/add_message.css'),
            template: require('./html/add_message.html'),
            controller: require('./js/add_message.js')
          })
        })
      }
    );
  }
}

可以在require里面将服务注入,如代码中的message.js。而为了将服务进行异步加载我们不能用普通的.factory或者.service。而需要调用$provide.factory或者$provide.service

如果采用webpack进行编译打包的话就需要webpack.optimize.CommonsChunkPlugin的支持,这样可以对js进行拆分打包,达到异步加载js的目的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js玩一玩WSH吧
Feb 23 Javascript
推荐20家国外的脚本下载网站
Apr 28 Javascript
js中的屏蔽的使用示例
Jul 30 Javascript
Javascript delete 引用类型对象
Nov 01 Javascript
$(document).ready(function() {})不执行初始化脚本
Jun 19 Javascript
深入探讨javascript中的数据类型
Mar 04 Javascript
js简单倒计时实现代码
Apr 30 Javascript
jQuery实现的模拟弹出窗口功能示例
Nov 24 Javascript
webpack实现热更新(实施同步刷新)
Jul 28 Javascript
JS实现table表格固定表头且表头随横向滚动而滚动
Oct 26 Javascript
js中实例与对象的区别讲解
Jan 21 Javascript
在layui框架中select下拉框监听更改事件的例子
Sep 20 Javascript
如何在AngularJs中调用第三方插件库
May 21 #Javascript
详解Angular-Cli中引用第三方库
May 21 #Javascript
Angular2安装angular-cli
May 21 #Javascript
Angular2使用Augury来调试Angular2程序
May 21 #Javascript
Angular2使用Angular-CLI快速搭建工程(二)
May 21 #Javascript
Angular2使用Angular CLI快速搭建工程(一)
May 21 #Javascript
jQuery获取单选按钮radio选中值与去除所有radio选中状态的方法
May 20 #jQuery
You might like
php 无限级数据JSON格式及JS解析
2010/07/17 PHP
thinkPHP下的widget扩展用法实例分析
2015/12/26 PHP
php与python实现的线程池多线程爬虫功能示例
2016/10/12 PHP
javascript实现 在光标处插入指定内容
2007/05/25 Javascript
JavaScript 验证浏览器是否支持javascript的方法小结
2009/05/17 Javascript
在服务端(Page.Write)调用自定义的JS方法详解
2013/08/09 Javascript
javascript多行字符串的简单实现方式
2015/05/04 Javascript
AngularJS实践之使用ng-repeat中$index的注意点
2016/12/22 Javascript
微信小程序 scroll-view隐藏滚动条详解
2017/01/16 Javascript
js实现分页功能
2017/05/24 Javascript
浅谈Postman解决token传参的问题
2018/03/31 Javascript
ng-repeat指令在迭代对象时的去重方法
2018/10/02 Javascript
Vue.js 图标选择组件实践详解
2018/12/03 Javascript
Node.js中出现未捕获异常的处理方法
2020/06/29 Javascript
[57:18]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#3VP VS VG
2016/03/03 DOTA
[50:58]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 Mineski vs EG
2018/04/03 DOTA
使用Python脚本将绝对url替换为相对url的教程
2015/04/24 Python
12步入门Python中的decorator装饰器使用方法
2016/06/20 Python
详解Python静态网页爬取获取高清壁纸
2019/04/23 Python
python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例
2020/02/28 Python
python爬取代理IP并进行有效的IP测试实现
2020/10/09 Python
python模拟点击在ios中实现的实例讲解
2020/11/26 Python
移动端Web页面的CSS3 flex布局快速上手指南
2016/05/31 HTML / CSS
JSF面试题:Jsf中的核心类用那些?有什么作用?LiftCycle六大生命周期是什么?
2014/07/17 面试题
现在输入n个数字,以逗号,分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset
2012/11/09 面试题
房地产销售员的自我评价分享
2013/12/04 职场文书
道德之星事迹材料
2014/05/03 职场文书
cf战队收人口号
2014/06/21 职场文书
社会学专业求职信
2014/07/17 职场文书
村干部群众路线整改措施思想汇报
2014/10/12 职场文书
2014年大班保育员工作总结
2014/12/02 职场文书
和谐拯救危机观后感
2015/06/15 职场文书
2016基督教会圣诞节开幕词
2016/03/04 职场文书
2021年国漫热度排行前十,完美世界上榜,第四是美国动画作品
2022/03/18 国漫
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏
MySQL优化之慢日志查询
2022/06/10 MySQL