Ember 控制器

2018-01-06 17:58 更新

從本篇開始進入第五章控制器,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。

1,控制器簡介

控制器與組件非常相似,由此,在未來的新版本中很有可能組件將會完全取代控制器,很可能隨著Ember版本的更新控制器將退出Ember。目前的版本中組件還不能直接通過路由訪問,需要通過模板調(diào)用才能使用組件,但是未來的版本會解決這個問題,到時候controller可能就真的從Ember退出了!

正因如此,模塊化的Ember應(yīng)用很少用到controller。即便是使用了controller也是為了處理下面的兩件事情:

  1. controller主要是為了維持當(dāng)前路由狀態(tài)。一般來說,model的屬性會保存到服務(wù)器,但是controller的屬性卻不會保存到服務(wù)器。
  2. 組件上的動作需要通過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屬性):

  • title
  • intro
  • body
  • author

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é)果:

結(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吧。您的肯定對我來說是最大的動力??!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號