详解angularjs利用ui-route异步加载组件
程序员文章站
2022-04-09 12:52:50
ui-route相比于angularjs的原生视图路由更好地支持了路由嵌套,状态转移等等。随着视图不断增加,打包的js体积也会越来越大,比如我在应用里面用到了wangedi...
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的目的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。