亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > WEB開發 > 正文

Ember Route

2024-04-27 15:13:45
字體:
來源:轉載
供稿:網友

簡介

Ember Route,路由管理,在ember中具有很重要的意義,他負責管理整個路由的規則,什么時候應該渲染什么模板等,總體來說,他的功能有

渲染一個模板加載model以供模板使用重定向到一個新的路由,比如說權限控制情況下,一個人不允許訪問某一個頁面可以負責處理一個action(動作或者事件)

基本配置

創建route

使用命令行創建ember g route <your-route-name>; 執行命令后,會在app/templates目錄下生成模板,會在app/routes目錄下生成js文件,同時修改app/route.js文件。

這里主要說明一下route.js文件,其基本格式為:

Router.map(function() { this.route('path1'); this.route('favorites', { path: '/path2' });});

當訪問/path1的時候,渲染path1模板,當訪問/path2的時候,渲染favorites模板。 如果是嵌套的路由(子路由),比如path1/path2,那么形式可能是這樣的, 創建的時候只需要ember g route path1/path2

Router.map(function() { this.route('path1',function(){ this.route('path2'); });});

如果想要設置初始頁面,可以這樣,這樣就可以為/設置一個初始的路由:

Router.map(function() { this.route('index',{path:'/'});});

如果url中具有動態的參數呢?例如localhost:8000/path1/path2/2,這個2可能是一個id,又或者localhost:8000/path1/path2/2/edit這可能代表一個id為2的數據的編輯頁面,那么在route.js可以如下表示:

Router.map(function() { this.route('path1', function(){ this.route('path2',{path:'/path2/:id'}); });});

通過這種方式,就可以進行訪問,但是注意,以上的形式下localhost:8000/path1/path2是無法訪問的。 在這種情況下,如何使用這個id參數呢?

//app/routes/path1/path2export default Ember.Route.extend({ model(params){ let id = params.id; return this.store.findRecord('model-example',id).then((data)=>{return data}); }});

如上就可以對參數進行使用。理論上來講,是不能夠修改url中的參數的,所以手動賦值是無效的,也無法進行刷新等動作。同時需要注意,不要給參數起一樣的名字,那樣就會不起作用,下面的李自力有2個id,所以不會起作用:

Router.map(function() { this.route('photo', { path: '/photo/:id' }, function() { this.route('comment', { path: '/comment/:id' }); });});

路由、模板的渲染規則

所有的路由都有一個根的父路由:application,也就是說,我們創建的所有路由,都是經由application渲染的。 我們我們查看模板文件,會發現路由的模板的內容都是{{outlet}}。每一個模板都會渲染到父模板的{{outlet}}上。一層一層的往上渲染。 比如經典的圣杯模型,在我們看來,可能上邊欄側邊欄和下邊欄是不變的,那么我們可以定義我們的application.hbs為:

<div class="header">這是上邊欄</div><div class="sider">這是側邊欄</div><div class="content">{{outlet}}</div><div class="footer">這是下邊欄</div>

那么渲染的時候,只會渲染到content中。 接下來我們講解一下渲染的規則。這里這篇文章介紹的非常好Ember.js 入門指南之十四番外篇,路由、模板的執行、渲染順序

渲染其他的模板也是允許的

一般情況下,我們要渲染的模板都是自己的哪一個,但是,ember也允許你渲染其他的模板,例如正常情況下,不做任何操作,path1/path2渲染的模板就是app/templates/path1/path2.hbs, 但是如果你想要進行更換,只需要重載方法renderTemplate()

//app/routes/path1/path2.jsexport default Ember.Route.extend({ renderTemplate() { this.render('path1/path2', { into: 'templateName', outlet: 'anOutletName' }); //this.render('path3');//這個語句可以使用path3替換path1/path2 }});

上面這個方法可以將path1/path2渲染到templateName 中使用{{outlet 'anOutletName'}}的地方。詳情請見render。

model的執行順序

model的執行順序為從主到子。例如urlpath1/path2,那么model的執行順序為application->path1->path2。

模板的渲染順序

首先,注意一點,就是,如果model執行完成后,才開始進行模板的渲染。 模板渲染的順序為從子到主,也就是path2->path1->application->path1。渲染完成后,展示。這里需要全部渲染完后展示。

路由的重定向

路由重定向,例如,當權限控制等的時候,跳轉到一個異常頁面等,常常會用到,常用方法為transitionTo()。transitionTo()的表現和helperlink-to的表現一致。另外還有一個方法replaceWith(),使用起來差不多。

transitionTo()可以在各個階段使用:

//app/routes/path1.jsexport default Ember.Route.extend({ //在model初始化之前(發送請求之前) beforeModel(){ this.transitionTo('/path2'); }, //在初始化的時候, model(){ return this.findRecord('model-example',1).then((data)=>{ if(!data){ this.transitionTo('/path2'); }else{ return data; } }); } //在model初始化之后 afterModel(){ let model = this.modelFor('path1'); if(model.length){ this.transitionTo('/path2'); } }, actions:{ //可以在action中,比如點擊后 transitionToPath2(){ this.transitionTo('/path2'); } }});

如果是要重定向到子路由,也可以直接在beforeModel() afterModel() model()中進行,但是如果這樣的,考慮到子路由的執行過程,會再次將父路由執行一次,所有,ember有一個更加優化的方式redirect

//app/routes/path1.jsredirect(model, transition) { this.transitionTo('path1.path2');}

還有一些高級的用法,比如復雜url或者帶參數的情況,注意這種情況下不能使用replaceWith進行替換:

//路由為 this.route('path2',{path:path2/:id});this.transitionTo('/path2/2');this.transitionTo('/path2',2);//同上{{link-to 'path2' 2}}//路由為 this.route('path2',{path:path2/:id}, function(){this.route('path3',{path:'path3/:p_id'})});this.transitionTo('/path2/2/paht3/3');{{link-to 'path2' 2 3}}//路由為this.route('path2',{path:path2/:id}); 且有參數`queryParams`(這個概念會在controller中說)this.transitionTo('/path2/2?params=1');this.transitionTo('/path2/2',{queryParams: { params: '1' }});//同上{{link-to 'path2' 2 (query-params params='1')}}

終止與重試路由跳轉

有一些情況下,我們可能需要手動終止路由的跳轉,或者是終止之后再重試。

當用戶通過{{link-to}}、transition方法或者直接執行URL來轉換路由,當前路由會自動執行willTransition方法。每個活動的路由都可以決定是否執行轉換路由。 如果你正在填寫一個表單,然后,無意點擊了跳轉,這樣你的填寫的數據就都丟失了,很不友好。所以一般會有一個確認頁面。所以我們可以通過willTransition來先讓用戶確認是否離開再說。

// app/routes/path1.jsimport Ember from 'ember';export default Ember.Route.extend({ actions: { willTransition: function(transition) { if (!confirm("你確定要離開這個頁面嗎?")) { transition.abort(); } else { return true; } } }});

load 以及 error的處理

我們假設有這樣的一個model:slow-model,這個model返回結果非常的慢,那么我們的以routedemo1/case1為例,如果route中加載情況如下:

model(){ return this.store.findAll('slow-model').then((data)=>{ return data; });}

那么,在slow-model返回結果之前,頁面會一直是空白,這個非常不美觀,我們一般會采用一個loading的圖標或者有一個提示等。

Ember提供的解決辦法是:在beforeModel、model、afterModel回調還沒返回前先進入一個叫loading的子狀態,然后渲染一個叫<your-route-name>-loading的模板(如果是application路由則對應的直接是loading、error不需要前綴)。

同樣以demo1/path1為例:

//app/templates/application.hbs<p>application</p><p>application</p><p>application</p>{{outlet}}//app/routes/demo1.jsimport Ember from 'ember';export default Ember.Route.extend({ model() { return this.store.findAll('slow-model'); }})//app/templates/demo1.hbs<p>demo1</p><p>demo1</p><p>demo1</p>{{outlet}}//app/templates/demo1-loading.hbs<p>demo1-loading</p><p>demo1-loading</p><p>demo1-loading</p>//app/routes/demo1/case1.jsimport Ember from 'ember';export default Ember.Route.extend({ model() { return this.store.findAll('slow-model'); }//app/templates/demo1/case1.hbs<p>case1</p><p>case1</p><p>case1</p>//app/templates/demo1/case1-loading.hbs<p>case1-loading</p><p>case1-loading</p><p>case1-loading</p>

以上的代碼,假設slow-model是非常慢的,那么頁面的展示順序為:

這里寫圖片描述 這里寫圖片描述 這里寫圖片描述

demo1/case1為例,結合我們說過的路由渲染順序為,注意,渲染順序還是從子到父的: - demo1.case1-loading - demo1-loading - loading(application的loading)

從上圖可以看出,在model沒有加載好的時候,會先用<your-route-name>-loading來對本來的模板進行替換。那么在這個過程中,model的執行順序呢?這個過程中,model為先執行父route的model,也就是demo1的model,當請求發出,直到下一個子路由的mode請求發出,一直都是loading狀態,也就是: 這里寫圖片描述 然后子路由請求發出,也就是demo1/case1請求發出后,進入子路由的loading狀態: 這里寫圖片描述 數據返回后,結束: 這里寫圖片描述

另外,在beforeModel、model、afterModel回調沒有立即返回之前,會先執行一個名為loading的事件。

actions: { loading: function(transition, originRoute) { alert("Sorry this is taking so long to load!!"); } }

loading事件實在model回調返回之前執行。這里需要注意一下,如果同時定義了loading回調,以及<your-route-name>-loading子模板,那么會只執行loading回調,而不會渲染模板。

error的情況也類似,不過過程是在model返回且失敗的情況下,而loading為未返回的情況下: 以demo1/case1為例,結合我們說過的路由渲染順序為,注意,渲染順序還是從子到父的(考慮到model的執行順序,不會出現父吧子覆蓋的情況,因為執行不到- -): - demo1.case1-error - demo1-error - error(application的error)

error的回調為:

actions: { error(error, transition) { if (error.status === '403') { this.replaceWith('login'); } else { // Let the route above this handle the error. return true; } } }

查詢參數

動態路由的情況,我們已經說過,但是,如果是帶參數呢?舉例,我們常用的分頁操作,一般都會帶上pageSize=10&pageNum=2意味著第二頁取10個,這樣,那么在請求中怎么做呢? 這里就要使用到controller的概念,對于路由demo1/case1而言,如果要增加參數,那么就需要創建相應的controller。創建controller:ember g controller demo1/case1,以分頁為例:

//app/controllers/demo1/case1.jsimport Ember from 'ember';export default Ember.Controller.extend({ queryParams: ['pageSize','pageNum'], pageSize: null, pageNum:null});

這樣就會在請求上帶上這個參數,如果你沒帶的話,還是會取到這個參數,只不過都是null罷了。你可以為他們設置默認值:

//app/controllers/demo1/case1.jsimport Ember from 'ember';export default Ember.Controller.extend({ queryParams: ['pageSize','pageNum'], pageSize: 10, pageNum:1});

那么默認就是第一頁的10個。注意,如果你傳的值就是和默認的一樣,在請求上是不會展示的!

關于查詢參數的用法,跳轉,在之前的transitionTo()方法以及link-to助手的的時候已經說過。

controller中還可以調用model的數據,以及使用計算屬性,官網上給出一個例子:

import Ember from 'ember';export default Ember.Controller.extend({ queryParams: ['category'], category: null, filteredArticles: Ember.computed('category', 'model', function() { var category = this.get('category'); var articles = this.get('model'); if (category) { return articles.filterBy('category', category); } else { return articles; } })});

這樣,filteredArticles的值就會一直隨著model的改變而改變,而filteredArticles的值是可以直接在模板中使用的,所以說間接的導致模板元素的變化。

關于查詢參數,還有一個點很重要,就是更新數據。因為畢竟url改變了,如果數據卻沒有更新的話,簡直不合理。

上述的做法相當于這樣:

this.transitionTo({ queryParams: { pageNum: 3 }});{{link-to (query-param pageNum=3)}}

注意,這種方式,由于沒有修改路由的結構,只不過是修改了參數,所以只能說是不完整的路由切換,這種不完整,也就意味著比如model和setupController回調方法就不會被執行,只是使得controller里的屬性值為新的查詢參數值以及更新URL。(當然,如果是跳轉到一個新的路由,還是會改變的)。

如果單純的按照上面的寫法,model是不會更新的。那么如何更新model中的數據呢?這需要你在對應的路由中配置一個名為queryParams哈希對象。并且需要設置一個名為refreshModel的查詢參數,這個參數的值為true。

import Ember from 'ember';export default Ember.Route.extend({ queryParams: { category: { refreshModel: true } }, model(params) { // This gets called upon entering 'articles' route // for the first time, and we opt into refiring it upon // query param changes by setting `refreshModel:true` above. // params has format of { category: "someValueOrJustNull" }, // which we can forward to the server. return this.get('store').query('article', params); }});

那么每次你修改參數后,都會更新model并且執行setupController。但是要注意,這個也會同時刷新父路由!

那么如果要手動觸發呢?比如搜索條件,你想要點擊搜索的時候才更新數據,或者說只更新自己的路由的信息,怎么辦呢?那么可以這么做

import Ember from 'ember';export default Ember.Route.extend({ model(){ console.log('model'); }, setupCotroller(controller,model){ console.log('setupcontroller'); }, actions:{ //如果只需要更新model clickAction(){ this.refresh(); }, //同時更新model以及setupcontroller clickAction1(){ let self = this, controller=this.get('controller'); this.model().then((data)=>{ controller.set('model', data); self.setupController(controller,data); }) } }});

異步路由

//TODO


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产综合久久久久| 欧美亚洲一区在线| 国产精品老牛影院在线观看| 久久久久久久国产精品视频| 91国内产香蕉| 欧美精品第一页在线播放| 日韩免费中文字幕| 中文字幕亚洲国产| 亚洲欧美日韩在线一区| 亚洲美女av在线播放| 欧美黄色免费网站| 91精品国产九九九久久久亚洲| 日本亚洲欧美成人| 日韩一区二区三区在线播放| 久久艹在线视频| 国产在线播放91| 欧美成人免费全部| 国产精品亚洲网站| 中文字幕亚洲一区二区三区| 亚洲欧美国产另类| 91亚洲永久免费精品| 欧洲永久精品大片ww免费漫画| 国产成人午夜视频网址| 色久欧美在线视频观看| 中文字幕亚洲专区| 欧美有码在线观看| 日韩美女免费视频| 日韩在线中文字幕| 欧美激情三级免费| 久久亚洲国产精品成人av秋霞| 欧美亚洲成人网| 91av免费观看91av精品在线| 欧美国产日韩二区| 成人免费直播live| 91久久久久久久久久久| 久久久久国产精品一区| 国内免费久久久久久久久久久| 国产主播喷水一区二区| 亚洲色在线视频| 美女福利视频一区| 国产精品成av人在线视午夜片| 伊是香蕉大人久久| 98视频在线噜噜噜国产| 中文字幕国产亚洲| 九色成人免费视频| 性欧美长视频免费观看不卡| 日韩av电影中文字幕| 一区二区在线视频播放| 久久久电影免费观看完整版| 精品久久久久久国产| 日韩av在线免费观看一区| 国产亚洲欧美日韩一区二区| 中文字幕亚洲无线码在线一区| 亚洲欧洲国产伦综合| 45www国产精品网站| 精品一区二区三区电影| 国产成人精品免费视频| 国产精品久久9| 久久久精品一区二区| 狠狠色狠狠色综合日日五| 亚洲国产女人aaa毛片在线| 91精品久久久久久久| 国产亚洲在线播放| 国产不卡视频在线| 亚洲色图17p| 精品国产乱码久久久久久天美| 不卡av在线网站| 欧美激情视频播放| 亚洲人成网站999久久久综合| 日本成人在线视频网址| 国模吧一区二区三区| 日韩成人激情影院| 亚洲人在线观看| 中文字幕亚洲无线码a| 久久资源免费视频| 日韩av123| 亚洲裸体xxxx| 色综合久久88色综合天天看泰| 亚洲一区二区三区乱码aⅴ蜜桃女| 91成人在线视频| 97视频在线观看成人| 亚洲精品福利在线观看| 久久精彩免费视频| 国产成人精品久久亚洲高清不卡| 亚洲a成v人在线观看| 91极品视频在线| 日本精品久久久久久久| 91国内免费在线视频| 日韩欧美第一页| 欧美日韩另类字幕中文| 91免费看片网站| 国内精品久久久久影院优| 欧美一区二区视频97| 亚洲人在线视频| 亚洲人成欧美中文字幕| 国产精品手机播放| 成人黄色在线观看| 91精品啪在线观看麻豆免费| 国产精品国产三级国产专播精品人| 国产欧美精品久久久| 成人激情黄色网| 日本a级片电影一区二区| 日韩极品精品视频免费观看| 成人中文字幕在线观看| 日韩电影大全免费观看2023年上| 国产69久久精品成人| 欧美精品一区二区三区国产精品| 中文字幕精品一区久久久久| 欧美www视频在线观看| 亚洲二区在线播放视频| 久久久久久国产| 91精品国产高清久久久久久久久| 欧美性xxxx在线播放| 国产不卡一区二区在线播放| 国产美女被下药99| 91国语精品自产拍在线观看性色| 欧美成人免费va影院高清| 国产精品美女呻吟| 国产精品三级久久久久久电影| 国产精品一香蕉国产线看观看| 久久久久日韩精品久久久男男| 成人av番号网| 国产精品久久综合av爱欲tv| 日本国产欧美一区二区三区| 国产精品第二页| 欧美激情综合色综合啪啪五月| 国产成人在线亚洲欧美| 欧美国产精品人人做人人爱| 日韩在线观看免费av| 国产精品pans私拍| 亚洲成人动漫在线播放| 色小说视频一区| 国产视频精品免费播放| 精品人伦一区二区三区蜜桃免费| 另类少妇人与禽zozz0性伦| 91理论片午午论夜理片久久| 国产一区视频在线播放| 久久天天躁狠狠躁夜夜躁| 国产精品自产拍高潮在线观看| 久久久极品av| 大桥未久av一区二区三区| 欧美日韩亚洲系列| 69影院欧美专区视频| 日本最新高清不卡中文字幕| 国产欧美日韩免费看aⅴ视频| 日韩欧美国产视频| 亚洲美女在线视频| 国产69久久精品成人| 国产精品高清免费在线观看| 中文字幕在线观看亚洲| 国产精品91久久久| 一区二区三区国产视频| 久久久精品999| 久久精品人人爽| 日韩中文字在线| 国产精品99免视看9| 91久久久久久国产精品| 亚洲成**性毛茸茸| 欧美在线播放视频| 国产精品人成电影在线观看| 日本久久中文字幕| 伊人精品在线观看| 97在线观看视频| 国产成人+综合亚洲+天堂|