W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
從本篇開始進入第五章控制器,controller
在Ember2.0
開始越來越精簡了,職責(zé)也更加單一——處理邏輯。
下面是準(zhǔn)備工作。 重新創(chuàng)建一個Ember項目,仍舊使用的是Ember CLI命令創(chuàng)建。
ember new chapter5_controllers
cd chapter5_controllers
ember server
在瀏覽器執(zhí)行項目,看到如下信息說明項目搭建成功。 Welcome to Ember。
控制器與組件非常相似,由此,在未來的新版本中很有可能組件將會完全取代控制器,很可能隨著Ember版本的更新控制器將退出Ember。目前的版本中組件還不能直接通過路由訪問,需要通過模板調(diào)用才能使用組件,但是未來的版本會解決這個問題,到時候controller
可能就真的從Ember退出了!
正因如此,模塊化的Ember應(yīng)用很少用到controller
。即便是使用了controller
也是為了處理下面的兩件事情:
controller
主要是為了維持當(dāng)前路由狀態(tài)。一般來說,model的屬性會保存到服務(wù)器,但是controller
的屬性卻不會保存到服務(wù)器。controller
層轉(zhuǎn)到route
層。
模板上下文的渲染是通過當(dāng)前controller
的路由處理的。Ember所追隨的理念是“約定優(yōu)于配置”,這也就意味著如果你只需要一個controller
你就創(chuàng)建一個,而不是一切為了“便于工作”。
下面的例子是演示路由顯示blog post
。假設(shè)模板blog-post
用于展示模型blog-post
的數(shù)據(jù),并在這個模型包含如下屬性(隱含屬性id
,因為在model
中不需要手動指定id
屬性):
model
定義如下:
// app/models/blog-post.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'), // 屬性默認(rèn)為string類型,可以不指定
intro: DS.attr('string'),
body: DS.attr('string'),
author: DS.attr('string')
});
在route
層增加測試數(shù)據(jù),直接返回一個model
對象。
// app/routes/blog-post.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var blogPost = this.store.createRecord('blog-post', {
title: 'DEFINING A COMPONENT', // 屬性默認(rèn)為string類型,可以不指定
intro: "Components must have at least one dash in their name. ",
body: "Components must have at least one dash in their name. So blog-post is an acceptable name, and so is audio-player-controls, but post is not. This prevents clashes with current or future HTML element names, aligns Ember components with the W3C Custom Elements spec, and ensures Ember detects the components automatically.",
author: 'ubuntuvim'
});
// 直接返回一個model,或者你可以返回promises,
return blogPost;
}
});
顯示信息的模板如下:
<h2>{{model.title}}</h2>
<h2>{{model.author}}</h2>
<div class="intro">
{{model.intro}}
</div>
<hr>
<div class="body">
{{model.body}}
</div>
如果你的代碼沒有編寫錯誤那么也會得到如下結(jié)果:
Welcome to Ember是主模板的信息,你可以在application.hbs
中刪除,但是記得不要刪除{{outlet}}
,否則什么信息也不顯示。
這個例子中沒有顯示任何特定的屬性或者指定的動作(action
)。此時,控制器的model屬性所扮演的角色僅僅是模型屬性的pass-through
(或代理)。
注意:控制器獲取的model
是從route
得到的。
下面為這個例子增加一個功能:用戶可以點擊標(biāo)題觸發(fā)顯示或者隱藏post
的內(nèi)容。通過一個屬性isExpanded
控制,下面分別修改模板和控制器的代碼。
// app/controllers/blog-post.js
import Ember from 'ember';
export default Ember.Controller.extend({
isExpanded: false, //默認(rèn)不顯示body
actions: {
toggleBody: function() {
this.toggleProperty('isExpanded');
}
}
});
在controller
中增加一個屬性isExpanded
,如果你不在controller
中定義這個屬性也是可以的。對于這個controller
代碼的解釋請看Ember.js 入門指南之十五{{action}} 助手。
<h2>{{model.title}}</h2>
<h2>{{model.author}}</h2>
<div class="intro">
{{model.intro}}
</div>
<hr>
{{#if isExpanded}}
<button {{action 'toggleBody'}}>hide body</button>
<div class="body">
{{model.body}}
</div>
{{else}}
<button {{action 'toggleBody'}}>Show body</button>
{{/if}}
在模板中使用if
助手判斷isExpanded
的值,如果為true
則顯示body
,否則不顯示。
頁面加載之后結(jié)果如下,首先是不顯示body
內(nèi)容,點擊按鈕“Show body”則顯示內(nèi)容,并且按鈕變?yōu)椤癶ide body”。然后在點擊這個按鈕則不顯示body
內(nèi)容。
到此controller
的職責(zé)你應(yīng)該大致了解了,其主要的作用是邏輯的判斷、處理,比如這里例子中判斷body
內(nèi)容的顯示與否,其實你也可以把controller
類中的處理代碼放在route
類中也可以實現(xiàn)這個效果,但是要作為model
的屬性返回(把isExpanded
當(dāng)做model
的屬性處理),請讀者自己動手試試,但是把邏輯放到route
又會使得route
變得“不專一”了,route
的主要職責(zé)是初始化數(shù)據(jù)的。我想這也是Ember還留著controller
的原因之一吧!!
博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能有出入,不過影響不大?。绻阌X得博文對你有點用,請在github項目上給我點個star
吧。您的肯定對我來說是最大的動力??!
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: