Emberjs之模組化路由,讓一切按需載入。
阿新 • • 發佈:2019-02-18
Emberjs的模組化很弱, 需要在html頁面中加入所有模板,引入所有的控制器,檢視。使這個html檔案很大,程式碼很多。
可能大家都想過要把模板放到外面獨立的檔案中,我也如此,所以實現了一個模組化的Ember路由,來實現此功能。
核心程式碼如下:
/* 動態載入路由所需的模版以及元件 */ (function() { Ember.USE_MODULE_ROUTE = true; var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach; var setupPromises = []; var setupFuns = []; //由於現在新的setup是非同步的,而Ember.Route的setup必須按順序執行, //所以此處維護一個佇列來確保Ember.Route的setup方法順序執行. function _runSetupQueue() { Ember.RSVP.all(setupPromises).then(function() { forEach(setupFuns, function(funObj) { var route = funObj.context; if(!route._abortRender){ funObj.fn.apply(route, funObj.args); } }); setupPromises.length = 0; setupFuns.length = 0; }); } /** 擴充套件Ember.Route {@link http://emberjs.com/guides/routing/defining-your-routes/|詳見原始文件}. @class Ember.Route */ Ember.Route.reopen({ /** 模版載入器的模組名 @memberof Ember.Route @default "text" @instance */ templateLoader: "text", /** 模版檔案的目錄 @memberof Ember.Route @default "./templates/" @instance */ templateDir: "./templates/", /** 該路由需要從templateDir目錄下請求的模版名陣列,如果只有一個,可以是字串. 如不指定該屬性, 只會將與路由名對應的模板加入請求列表. 如果指定了該屬性, 則只會請求該屬性指定的模版. 所以,可以將該屬性設定為空陣列[], 則不會請求任何模版. @memberof Ember.Route @default null @instance */ templateNames: null, /** 該路由需要用到的元件類. @memberof Ember.Route @default null @instance */ dependences: null, exit: function() { this._abortSetup = true; this._super(); }, setup: function(context) { this._abortSetup = false; var setupPromise = this._setup(); setupPromises.push(setupPromise); setupFuns.push({ fn: this.__nextSuper, args: [context], context: this }); Ember.run.once(null, _runSetupQueue); }, _setup: function() { var route = this; return new Ember.RSVP.Promise(function(resolve, reject) { var routeName, TEMPLATES, templateLoader, templateDir, tplNames, dependences, depsTplNames, depsTplUrls; if (route.constructor != "Ember.Route") { routeName = route.routeName.replace(/\./g, '/'); } TEMPLATES = Ember.TEMPLATES; templateLoader = route.templateLoader; templateDir = route.templateDir; tplNames = route.templateNames; if(Ember.USE_MODULE_ROUTE){ tplNames = tplNames || routeName || []; } else { tplNames = tplNames || []; } tplNames = typeof tplNames == "string" ? [tplNames] : [].concat(tplNames); dependences = route.dependences || []; dependences = typeof dependences == "string" ? [dependences] : [].concat(dependences); depsTplNames = []; depsTplUrls = []; forEach(tplNames, function(tplName, i, self) { if (!TEMPLATES.hasOwnProperty(tplName)) { depsTplNames.push(tplName); depsTplUrls.push(templateLoader + "!" + templateDir + tplName + ".hbs"); } }); dependences = [].concat(depsTplUrls, dependences); if(dependences.length == 0){ Ember.run(null, resolve); }else{ require(dependences, function() { var modules = arguments; forEach(depsTplNames, function(tplName, i) { TEMPLATES[tplName] = Ember.Handlebars.compile(modules[i]); }); Ember.run(null, resolve); }); } }); } }); })();