[英]Understand routing in Ember.js
我真的很難理解Ember中的路由概念,但比它看起來更復雜。 來自doc。 每當有不同的URL或路徑時,你可以看到你有不同的路由,如果你在同一個url中有不同的路徑,你只需要創建一個嵌套模板。 但是當你在一個網址中有3條不同的路徑時呢?
和this.resource和this.route的區別是什么?
由於實例總是比純理論更好,這里是我的應用程序。 在索引或'/'中我應該呈現“列表模板”,“新模板”,當用戶點擊列表鏈接時,“注釋模板”將呈現為“新模板”。
我的路由器:
Notes.Router.map(function () {
this.resource('index', { path: '/' }, function (){
this.resource('list', {path: ':note_title'});
this.resource('new', {path: '/'});
this.resource('note', { path: ':note_id' });
});
});
我的模板:
<script type="text/x-handlebars" data-template-name="index">
<div class="wrap">
<div class="bar">
{{input type="text" class="search" placeholder="Where is my bookmark??" value=search action="query"}}
<div class="bar-buttons">
<button {{action "addNote"}}> NEW </button>
</div>
</div>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="list">
<aside>
<h4 class="all-notes">All Notes {{length}}</h4>
{{#each item in model}}
<li>
{{#link-to 'note' item}} {{item.title}} {{/link-to}}
</li>
{{/each}}
</aside>
</script>
<script type="text/x-handlebars" data-template-name="new">
<section>
<div class="note">
{{input type="text" placeholder="Title" value=newTitle action="createNote"}}
<div class="error" id="error" style="display:none"> Fill in the Title! </div>
{{input type="text" placeholder="What you need to remember?" value=newBody action="createNote"}}
{{input type="text" placeholder="Url:" value=newUrl action="createNote"}}
</div>
</section>
</script>
<script type="text/x-handlebars" data-template-name="note">
<section>
<div class="note">
{{#if isEditing}}
<h2 class="note-title input-title"> {{edit-input-note value=title focus-out="modified" insert-newline="modified"}} </h2>
<p class="input-body"> {{edit-area-note value=body focus-out="modified" insert-newline="modified"}} </p>
{{edit-input-note value=url focus-out="modified" insert-newline="modified"}}
{{else}}
<h2 {{action "editNote" on="doubleClick"}} class="note-title" > {{title}} </h2>
<button {{action "removeNote"}} class="delete"> Delete </button>
<p {{action "editNote" on="doubleClick"}}> {{body}} </p>
{{input type="text" placeholder="URL:" class="input" value=url }}
{{/if}}
</div>
</section>
</script>
或者在這里Js Bin: http : //jsbin.com/oWeLuvo/1/edit?html ,js, output
如果需要我的控制器或模型,我也會添加該代碼。 提前致謝
你的例子似乎有效。
你只是想念依賴。 你沒有包括Handlebars和Ember.data
如果您已經檢查過您的javascript控制台,那么您已經看到了錯誤。
工作示例: http : //jsbin.com/oWeLuvo/2/
在Ember,資源和路線都是路線。 它們有兩個名稱,以便Ember區分資源和路徑。 老實說要記住,它們都是路線,為了保持理智,你可以將它們分別稱為“資源路線”和“路線”。 資源可以嵌套並具有嵌套在其中的子資源或路由。 另一方面,路由不能嵌套任何東西。
如果您尚未使用,請安裝 Ember Inspector 。 它是一個Chrome擴展程序,可以幫助您安裝路由器,控制器,模板,數據以及安裝在Chrome Web瀏覽器中的其他很多其他東西。 我聽說Ember Inspector的最后一個也可以在FireFox Dev Tools中找到。 https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi?hl=en
因此,如果有資源,您可以嵌套資源和路由。 嵌套資源將保留其名稱空間,路由將附加到嵌套名稱空間。 請記住,您不能在路線中嵌套任何東西。
App.Router.map(function() {
//creating a resource
this.resource('foo', {path: 'somePathYouPut'}, function() {
//nesting stuff inside of the resource above
//could open another nest level here in bar if you want
this.resource('bar');
//can not nest in route. Sad face. Sorry
this.route('zoo');
});
});
由於您無法將任何內容嵌套到路徑中,因此index
模板中的{{outlet}}沒有要查找的子項,默認情況下會呈現為{{outlet}}。 我相信這就是你認為會發生的事情。
<script type="text/x-handlebars" data-template-name="index">
<div class="wrap">
<div class="bar">
{{input type="text" class="search"
placeholder="Where is my bookmark??" value=search action="query"}}
<div class="bar-buttons">
<button {{action "addNote"}}> NEW </button>
</div>
</div>
{{outlet}}
</div>
</script>
在您的代碼中,您將index
稱為資源,它是一個路由。 由於索引是一個路由,記住你不能在一個路由中嵌套元素,你的代碼看起來應該更像這樣。 此外,您的resource
“新”路/
也可被移除。
Notes.Router.map(function () {
//this is a route not a resource you had it as resource
//and tried to nest in your code
this.route('index', { path: '/' });
this.resource('list', {path: ':note_title'});
this.resource('new');
this.resource('note', { path: ':note_id' });
});
您在每個嵌套級別獲得一個index
,從應用程序級別的最高級別開始,但您不必在路由器中明確定義它們。 您在每個嵌套級別免費獲得的index
路由默認情況下與其直接父級關聯,並默認情況下呈現到其父級“插座”。 您可以認為路由器看起來像這樣。
僅用於說明目的:
Notes.Router.map(function() {
//think of this as your application level stuff that Ember just does!!
//this is not written like this but to illustrate what is going on
//you would get application template, ApplicationRoute, ApplicationController
this.resource('application', function() {
//this is an index that you get for free cause its nested
//its that index template, IndexController, and IndexRoute you were using
this.route('index', { path: '/' });
this.resource('foo', {path: 'somePathYouPutHere' }, function() {
//since you started another nested level surprise you get another `index`
//but this one is `foo/index` template.
this.route('index', {path: '/'});
this.route('zoo');
});
});
});
上面誇大的路由器示例的第一部分,Ember會自動在幕后,它是你聽到的“魔法”的一部分。 它為自己設置一個應用程序環境做了兩件事,你得到了ApplicationRoute
, ApplicationController
和一個總是在幕后的application
模板。 其次,它會生成該index
並獲得IndexController
,IndexRoute和可以使用或忽略的index
模板。 因此,如果您不執行任何其他操作,則無法在var App = Ember.Application.create();
等文件中聲明和Ember App的其他代碼var App = Ember.Application.create();
並打開Ember Inspector並查看您將看到上述資產的路線。
現在,上面路由器中的資源foo
就是你要做的資源的一個例子,當你看到你在那里得到一個index
因為你開始嵌套了。 如上所述,您不必在每個嵌套級別定義索引, this.route('index', {path: '/'});
從內部foo
可以完全省略,Ember仍然會做同樣的事情。 最終將使用foo/index
模板, FooIndexRoute
, FooIndexController
以及預期的foo
模板, FooRoute
和FooController . You can think of the
. You can think of the
foo index as a place that says 'hey' before anything else gets rolled into my parent
foo index as a place that says 'hey' before anything else gets rolled into my parent
並且被渲染index as a place that says 'hey' before anything else gets rolled into my parent
如果你願意我可以展示一些東西,使用我。
這也是一個很好的時機來突出在上面的例子中在像this.route('zoo')
這樣的資源中嵌套路由時命名空間會發生什么。 路由zoo
的命名空間現在將被附加到資源foo
,最終會得到foo/zoo
模板, FooZooRoute
和FooZooController
。
如果你要將zoo更改為嵌套在foo資源this.resource('zoo');
中的資源this.resource('zoo');
命名空間將保留給動物園。 最終將使用'zoo'模板, ZooRoute
和ZooController
。 保留名稱空間。 好的,足夠的一面跟蹤你的應用程序。
你說你想要/
你的應用程序的url來呈現list template
。 為了實現這一點,您必須覆蓋Ember啟動時發生的默認行為。 您可以通過將{path: '/'}
到路由器中的第一個資源或路由來覆蓋頂級/
。 從您獲得的第一個index
路由上方的虛假路由器代碼與應用程序關聯。 默認情況下,如果不執行任何操作,Ember會將該index
模板推送到application
模板中。 但是,如果您為應用程序點擊/
'的基本URL,則不希望將list
模板推送到應用程序模板中。
Notes.Router.map(function() {
this.resource('list', {path: '/'});
this.resource('new');
this.resource('note', { path: ':note_id' });
});
通過像我上面那樣將代碼{path: '/'}
到第一個資源,你現在告訴Ember'嘿'當我的app url到達/
的基本URL時或者當你啟動時使用我的列表模板而不是你的默認index
模板並將其呈現到應用程序模板中。 此外,由於當您的應用程序通過URL轉換到這些路徑時,其他資源不會嵌套,因此它們會在應用程序模板{{outlet}}中顯示出什么,並在那里替換它們自己。
你提到過在路由中定義一個“路徑”,它告訴Ember你想如何在url中表示該路由。 在上面的示例中,如果保留新資源,默認情況下,Ember將使用路由名稱作為路徑,url將為/new
。 您可以在新資源的路徑中放置任何名稱, this.resource(new, {path :'emberMakesMeKingOfWorld'});
並且該名稱將在URL中表示為/emberMakesMeKingOfWorld
並且該長項仍將與您的新路由相關聯。 您的用戶可能會對這個網址的含義感到困惑,但在您知道它與您的新路線綁定的情況之后。 它只是一個示例,但可能是使用描述性名稱的良好做法,以便您的用戶知道在您的應用程序中擊中網址的目的是什么。
覆蓋與應用程序關聯的默認index
模板后。 我將您的代碼移動到應用程序模板中。 原因似乎是你希望那個帶有'newNote'動作的欄一直存在。 如果你想在你的應用程序中一直存在一些東西,比如導航欄,頁腳,我相信你可以想到更好的東西,把它放在應用程序模板中。
這是一個JSBIN,我調整了一些代碼
我希望這有助於Happy Coding。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.