详解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 相关文章推荐
Javascript变量函数浅析
Sep 02 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
Nov 19 Javascript
AngularJs实现分页功能不带省略号的代码
May 30 Javascript
JavaScript实现url参数转成json形式
Sep 25 Javascript
JS判断输入的字符串是否是数字的方法(正则表达式)
Nov 29 Javascript
AngularJS中的拦截器实例详解
Apr 07 Javascript
JS设计模式之惰性模式(二)
Sep 29 Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
Nov 22 Javascript
JavaScript函数apply()和call()用法与异同分析
Aug 10 Javascript
jQuery实现动态添加和删除input框实例代码
Mar 26 jQuery
在Vue mounted方法中使用data变量详解
Nov 05 Javascript
js实现模拟购物商城案例
May 18 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长字符串定义方法
2012/07/12 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
2018/06/14 PHP
PHP的重载使用魔术方法代码实例详解
2021/02/26 PHP
PHP安装扩展mcrypt以及相关依赖项深入讲解
2021/03/04 PHP
Jquery 选中表格一列并对表格排序实现原理
2012/12/15 Javascript
jQuery图片滚动图片的效果(另类实现)
2013/06/02 Javascript
javascript中的self和this用法小结
2014/02/08 Javascript
Nodejs实现多人同时在线移动鼠标的小游戏分享
2014/12/06 NodeJs
node.js中的forEach()是同步还是异步呢
2015/01/29 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
NodeJs下的测试框架Mocha的简单介绍
2017/02/22 NodeJs
从零开始学习Node.js系列教程二:文本提交与显示方法
2017/04/13 Javascript
详解vue mixins和extends的巧妙用法
2017/12/20 Javascript
jQuery中each方法的使用详解
2018/03/18 jQuery
在webstorm开发微信小程序之使用阿里自定义字体图标的方法
2018/11/15 Javascript
图片文字识别(OCR)插件Ocrad.js教程
2018/11/26 Javascript
JavaScript模板引擎实现原理实例详解
2018/12/14 Javascript
vue slot与传参实例代码讲解
2019/04/28 Javascript
微信小程序template模板与component组件的区别和使用详解
2019/05/22 Javascript
[06:04]DOTA2国际邀请赛纪录片:Just For LGD
2013/08/11 DOTA
python 中的int()函数怎么用
2017/10/17 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
基于Python函数的作用域规则和闭包(详解)
2017/11/29 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
2018/06/11 Python
如何用C代码给Python写扩展库(Cython)
2019/05/17 Python
PyQt5实现QLineEdit添加clicked信号的方法
2019/06/25 Python
python3.6 tkinter实现屏保小程序
2019/07/30 Python
详解python中index()、find()方法
2019/08/29 Python
QML使用Python的函数过程解析
2019/09/26 Python
python识别验证码的思路及解决方案
2020/09/13 Python
基于HTML5 Canvas 实现弹出框效果
2017/06/05 HTML / CSS
幼儿园教研活动方案
2014/01/19 职场文书
活动策划邀请函
2014/02/06 职场文书
2014年公司迎新年活动方案
2014/02/24 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书