当前位置: 移动技术网 > IT编程>脚本编程>AngularJs > 详解angularjs利用ui-route异步加载组件

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

2018年04月26日  | 移动技术网IT编程  | 我要评论

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的目的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网