在Ember中路由和模板的執(zhí)行都是有一定順序的,它們的順序?yàn)椋褐髀酚?>子路由1->子路由2->子路由3->……。模板渲染的順序與路由執(zhí)行順序剛好相反,從最后一個(gè)模板開(kāi)始解析渲染。
注意:模板的渲染是在所有路由執(zhí)行完之后,從最后一個(gè)模板開(kāi)始。關(guān)于這一點(diǎn)下面的代碼會(huì)演示驗(yàn)證,官網(wǎng)教程有介紹,點(diǎn)擊查看。
比如有一路由格式為application/posts/detail/comments/comment
,此時(shí)路由執(zhí)行的順序?yàn)椋?code>application/posts -> detail
-> comments
-> comment
,application
是項(xiàng)目默認(rèn)的路由,用戶自定義的所有路由都是application
的子路由(默認(rèn)情況下),相對(duì)應(yīng)的模板也是這樣,所有用戶自定義的模板都是application.hbs
的子模板。如果你要修改模板的渲染層次你可以在route
中重寫(xiě)renderTemplate
回調(diào)函數(shù),在函數(shù)內(nèi)使用render
方法指定要渲染的模板(如:render('other')
,渲染到other
這個(gè)模板上)更多有關(guān)信息請(qǐng)查看這里。并且它們對(duì)應(yīng)的文件模板結(jié)構(gòu)如下圖:
路由與模板是相對(duì)應(yīng)的,所以模板的目錄結(jié)構(gòu)與路由的目錄結(jié)構(gòu)是一致的。 你有兩種方式構(gòu)建上述目錄:
comment.js
使用命令:ember generate route posts/detail/comments/comment
,Ember CLI會(huì)自動(dòng)為我們創(chuàng)建目錄和文件。創(chuàng)建好目錄結(jié)構(gòu)之后我們添加一些代碼到每個(gè)文件。運(yùn)行項(xiàng)目之后你就會(huì)一目了然了……。 下面我按前面講的路由執(zhí)行順序分別列出每個(gè)文件的內(nèi)容。
// app/routes/posts.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
console.log('running in posts...');
return { id: 1, routeName: 'The route is posts'};
// return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
}
});
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
console.log('params id = ' + params.post_id);
console.log('running in detail....');
return { id: 1, routeName: 'The route is detail..' };
}
});
// app/routes/posts/detail.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
console.log('params id = ' + params.post_id);
console.log('running in detail....');
return { id: 1, routeName: 'The route is detail..' };
}
});
// app/routes/posts/detail/comments.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
console.log('running in comments...');
return { id: 1, routName: 'The route is comments....'};
}
});
// app/routes/posts/detail/comments/comment.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
console.log('params id = ' + params.post_id);
console.log('running in comment...');
return { id: 1, routeName: 'The route is comment...'};
}
});
下面是模板各個(gè)文件的內(nèi)容。其列出才順序與路由的順序一致。
{{model.routeName}} >> {{outlet}}
{{model.routeName}} >> {{outlet}}
{{model.routeName}} >> {{outlet}}
{{model.routeName}} >> {{outlet}}
下圖是路由執(zhí)行的順序,并且在執(zhí)行的過(guò)程中渲染路由對(duì)應(yīng)的模板。
從上圖中可用清楚的看到當(dāng)你運(yùn)行一個(gè)URL時(shí),與URL相關(guān)的路由是怎么執(zhí)行的。
application
),此時(shí)進(jìn)入到路由的model
回調(diào)方法,并且返回了一個(gè)對(duì)象{ id: 1, routeName: 'The route is application...' }
,執(zhí)行完回調(diào)之后繼續(xù)轉(zhuǎn)到子路由執(zhí)行直到最后一個(gè)路由執(zhí)行完畢,所有的路由執(zhí)行完畢之后開(kāi)始渲染頁(yè)面。detail.js
和
comments.js
。在代碼中加入一個(gè)模擬休眠的操作。
// app/routes/posts/detail.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) { console.log('params id = ' + params.post_id); console.log('running in detail....');
// 執(zhí)行一個(gè)循環(huán),模擬休眠 for (var i = 0; i < 10000000000; i++) {
}
console.log('The comment route executed...');
return { id: 1, routeName: 'The route is detail..' }; } });
```javascript
// app/routes/posts/detail/comments.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
console.log('params id = ' + params.post_id);
console.log('running in comment...');
// 執(zhí)行一個(gè)循環(huán),模擬休眠
for (var i = 0; i < 10000000000; i++) {
}
return { id: 1, routeName: 'The route is comment...'};
}
});
刷新頁(yè)面,注意查看控制臺(tái)輸出信息和頁(yè)面顯示的內(nèi)容。 新開(kāi)一個(gè)窗口,執(zhí)行URL:http://localhost:4200/posts/2/comments。
控制臺(tái)輸出到這里時(shí)處理等待(執(zhí)行for
循環(huán)),此時(shí)已經(jīng)執(zhí)行了兩個(gè)路由application
和posts
,并且正在執(zhí)行detail
,但是頁(yè)面是空白的,沒(méi)有任何HTML元素。
在detail
路由執(zhí)行完成之后轉(zhuǎn)到路由comments
。然后執(zhí)行到for
循環(huán)模擬休眠,此時(shí)頁(yè)面仍然是沒(méi)有任何HTML元素。然后等到所有route
執(zhí)行完畢之后,界面才顯示model
回調(diào)里設(shè)置的信息。
每個(gè)子路由設(shè)置的信息都會(huì)渲染到最近一個(gè)父路由對(duì)應(yīng)模板的{{outlet}}
上面。
comment
得到的內(nèi)如為:“comment
渲染完成”comment
最近的父模板comments
得到的內(nèi)容為:“comment
渲染完成 comments
渲染完成”comments
最近的父模板detail
得到的內(nèi)容為:“comment
渲染完成 comments
渲染完成 detail
渲染完成”detail
最近的父模板posts
得到的內(nèi)容為:“comment
渲染完成 comments
渲染完成 detail
渲染完成 posts
渲染完成”posts
最近的父模板application
得到的內(nèi)容為:“comment
渲染完成 comments
渲染完成 detail
渲染完成 posts
渲染完成 application
渲染完成”
只要記住一句話:子模板的都會(huì)渲染到父模板的{{outlet}}
上,最終所有的模板都會(huì)被渲染到application
的{{outlet}}
上。
博文完整代碼放在Github(博文經(jīng)過(guò)多次修改,博文上的代碼與github代碼可能又出入,不過(guò)影響不大?。绻阌X(jué)得博文對(duì)你有點(diǎn)用,請(qǐng)?jiān)趃ithub項(xiàng)目上給我點(diǎn)個(gè)star
吧。您的肯定對(duì)我來(lái)說(shuō)是最大的動(dòng)力??!
更多建議: