自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

點(diǎn)燃圣火!Ember.js 的初學(xué)者指南

開發(fā) 前端
現(xiàn)在,到處都可以看到復(fù)雜的 JavaScript 應(yīng)用程序。 由于這些應(yīng)用程序變得越來越復(fù)雜,一長串的 jQuery 回調(diào)語句,或者通過應(yīng)用程序在各個(gè)點(diǎn)執(zhí)行不同的函數(shù)調(diào)用,這些都變得無法再讓人接受。 這導(dǎo)致了 JavaScript 開發(fā)人員了解到傳統(tǒng)的軟件程序員已經(jīng)知道了幾十年的問題: 組織和效率非常重要,并且可以對(duì)應(yīng)用程序的性能是否優(yōu)異產(chǎn)生重大影響。

現(xiàn)在,到處都可以看到復(fù)雜的 JavaScript 應(yīng)用程序。 由于這些應(yīng)用程序變得越來越復(fù)雜,一長串的 jQuery 回調(diào)語句,或者通過應(yīng)用程序在各個(gè)點(diǎn)執(zhí)行不同的函數(shù)調(diào)用,這些都變得無法再讓人接受。 這導(dǎo)致了 JavaScript 開發(fā)人員了解到傳統(tǒng)的軟件程序員已經(jīng)知道了幾十年的問題: 組織和效率非常重要,并且可以對(duì)應(yīng)用程序的性能是否優(yōu)異產(chǎn)生重大影響。

實(shí)現(xiàn)組織和效率的其中一個(gè)最常用的架構(gòu)模式,被稱為 Model View Controller (縮寫為 MVC) 。 這種模式鼓勵(lì)開發(fā)人員將其應(yīng)用程序的不同部分分割為更易于管理的塊。 您不必使用一個(gè)函數(shù)直接調(diào)用數(shù)據(jù)庫,您可以創(chuàng)建了一個(gè) Model(模型)來為您管理數(shù)據(jù)庫。 您不必使用一個(gè)布滿輸出和邏輯語句的 HTML文件,一個(gè)簡單的模板或 View(視圖)就可以您簡化顯示代碼。 最后,Controller(控制器)管理您的應(yīng)用程序的流,幫助各種零散的部件更高效地互相溝通。 在您的應(yīng)用程序中使用這個(gè)模式,可以更輕松地增加新的功能。

作為最近爆發(fā)的基于 Internet 的軟件開發(fā)的一部分,出現(xiàn)了一堆令人眼花繚亂的 MVC 框架,比如 Ember.js、Backbone.js、Knockout.js、Spine.js、Batman.js 和 Angular.js。 一方面是初級(jí)和中級(jí)開發(fā)人員,另一方面是骨灰級(jí)程序員,以 JavaScript 編寫并針對(duì) JavaScript 開發(fā)而設(shè)計(jì)的這些庫補(bǔ)充了這兩者之間的空白。 它們提供多種特性和功能,根據(jù)開發(fā)人員的需求滿足技能水平各異的不同開發(fā)人員。

在本教程中,您將通過構(gòu)建一個(gè)可用的 Twitter 時(shí)間軸查看器,更熟悉 Ember.js。

Ember.js 簡介

Ember.js 是 JavaScript 框架包中最新的成員之一。 它演變出了最初于 2007 年創(chuàng)建的 SproutCore 項(xiàng)目,Apple 在包括 MobileMe 在內(nèi)的各種 web 應(yīng)用程序中大量使用了該項(xiàng)目。 在 emberjs.com,Ember 被形容為 "一個(gè) JavaScript 框架,用于創(chuàng)建可以消除樣板并提供標(biāo)準(zhǔn)應(yīng)用程序架構(gòu)的大型 web 應(yīng)用程序。" 它本身緊密集成了名為 Handlebars 的模板引擎,該引擎為 Ember 提供了其中一個(gè)最強(qiáng)大的功能: 雙向數(shù)據(jù)綁定。 Ember 還提供了其他功能,比如狀態(tài)管理(某個(gè)用戶狀態(tài)是已注銷還是已登錄)、自動(dòng)更新模板(當(dāng)?shù)讓訑?shù)據(jù)發(fā)生變化時(shí),您的 UI 也同樣發(fā)生變化)以及計(jì)算屬性 (firstName + lastName = fullName)。 Ember 經(jīng)過一年可靠的開發(fā)后,已經(jīng)成為一個(gè)強(qiáng)大的參與者。

Ember 只有一個(gè)依賴項(xiàng)—jQuery。 Ember 應(yīng)用程序的樣板 HTML 設(shè)置看起來應(yīng)該與下面的代碼類似。 請(qǐng)注意,jQuery 和 Ember 都從 CDN(內(nèi)容交付網(wǎng)絡(luò))進(jìn)行更新。 如果用戶在早些時(shí)候訪問需要這些文件的其他網(wǎng)站時(shí)已經(jīng)下載過這些文件,這會(huì)加快用戶的頁面加載速度。

  1. <html> 
  2. <head> 
  3. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
  4. </script> 
  5. <script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.6.min.js">
  6. </script> 
  7. <script src="js/app.js">
  8. </script> 
  9. </head> 
  10. <body> 
  11. </body>
  12.  </html> 

定義 MVC

在您繼續(xù)本教程之前,更明確地定義 MVC 可能會(huì)是一個(gè)好主意。 這個(gè)概念在 1979 年已經(jīng)出現(xiàn),自那時(shí)以來,該模式已經(jīng)出現(xiàn)一些不同的變體。 最常見的流程通常是這樣的:

  1. 用戶執(zhí)行一個(gè)操作,比如敲擊鍵盤或單擊鼠標(biāo)按鈕。
  2. 控制器接收輸入并觸發(fā)一個(gè)消息給模型。
  3. 模型根據(jù)消息修改其內(nèi)容(刪除一行或更新購物車數(shù)量)。
  4. 視圖監(jiān)視模型中的變更,并相應(yīng)地更新用戶界面。

了解 MVC 模式的工作方式,可以使您的應(yīng)用程序流動(dòng)變得更簡單。 此外,由于代碼被分割成不同的塊,開發(fā)人員團(tuán)隊(duì)能夠更輕松地協(xié)同工作,且不互相干擾。

Ember 如何執(zhí)行 MVC

JavaScript 是一個(gè)靈活而強(qiáng)大的語言,但它也有不足之處。 它不提供那種使自己適合于 MVC 風(fēng)格開發(fā)的開箱即用的功能。 因此 Ember 利用一批額外功能擴(kuò)展了該基本語言。 在構(gòu)建 Ember 應(yīng)用程序時(shí),您會(huì)使用四個(gè)主要部件: Application(應(yīng)用程序)、Model(模型)、View(視圖)和 Controller(控制器)。 以下各節(jié)將回顧每個(gè)部件。

Application(應(yīng)用程序)

每個(gè) Ember 應(yīng)用程序都需要一個(gè) Ember.Application 實(shí)例。這是代碼其余所有部分的基礎(chǔ),它提供有用的功能,以及名稱空間(對(duì)應(yīng)用程序的其余部件進(jìn)行分組的一種方式)。 定義一個(gè) Ember 應(yīng)用程序很簡單:

  1. Songs = Ember.Application.create({ mixmaster: 'Andy' }); 

該代碼定義一個(gè)名為 Songs 的應(yīng)用程序,將其名為 mixmaster 的屬性設(shè)置為 Andy 。 您可以將應(yīng)用程序的名稱改為您喜歡的任何名稱,但 Ember 要求變量的名稱以一個(gè)大寫字母開始,以便綁定的系統(tǒng)可以找到它。 在創(chuàng)建應(yīng)用程序時(shí)還可以添加其他內(nèi)置選項(xiàng),并且您也可以添加任意的屬性或方法,但初學(xué)者用戶主要關(guān)心的可能是 ready() 方法。 該方法的工作方式與 jQuery 的 document.ready() 塊完全一樣,并且能夠通過以下方式實(shí)現(xiàn):

  1. Songs = Ember.Application.create({ mixmaster: 'Andy', totalReviews: 0, ready: function(){ alert('Ember sings helloooooooooo!'); } }); 

Models(模型)

如果沒有數(shù)據(jù),應(yīng)用程序就沒有意義。 Ember 使用 Models 幫助開發(fā)人員以結(jié)構(gòu)化的方式管理數(shù)據(jù)。 除了保存數(shù)據(jù)之外,Ember Models 也對(duì)其內(nèi)部的數(shù)據(jù)進(jìn)行建模。 換句話說,如果您想儲(chǔ)存有關(guān) MP3 集合的信息,您的模型可能包含一個(gè)標(biāo)題屬性、一個(gè)藝術(shù)家屬性和一個(gè)流派屬性等。 該模型可能看起來如下所示:

  1. Songs.Song = Ember.Object.extend({ title: null, artist: null, genre: null, listens: 0 }); 

關(guān)于這幾行代碼,還有幾件事情要注意。

  • 您馬上就可以看到您的應(yīng)用程序在使用的名稱空間。 Songs 是應(yīng)用程序的名稱,而 Song 是模型的名稱。
  • 當(dāng)擴(kuò)展對(duì)象時(shí),您是在為此模型的未來實(shí)例創(chuàng)建藍(lán)圖。 因?yàn)檫@是 主 因?yàn)檫@是主對(duì)象,所有歌曲將以它為基礎(chǔ),所以它使用一個(gè)大寫字母。 這些命名約定使得您在將來可以更輕松地分辨正在使用的對(duì)象類型。
  • 在創(chuàng)建模型時(shí),您可以為每個(gè)屬性提供默認(rèn)值。 title、 artist 和 genre 屬性可在以后填寫,所以被標(biāo)記為 null (或無)。 listens 屬性默認(rèn)為 0 ,并且它的值將在您聽音樂收藏時(shí)增加。

現(xiàn)在, Song 模型已到位,您可以添加第一首歌曲。 您使用了 extend 來初始化 Song 模型,但您將使用 create 來添加它的一個(gè)實(shí)例。 下面是它的樣子:

  1. mySong = Song.create({ title: 'Son of the Morning', artist: 'Oh, Sleeper', genre: 'Screamo' }); 

請(qǐng)注意,變量沒有以一個(gè)大寫字母開始,那是因?yàn)樗?Song 模型的一個(gè)實(shí)例。 新的歌曲也不在 Songs 名稱空間中。 您將幾乎不再需要在您的應(yīng)用程序中創(chuàng)建模型的實(shí)例。 您這樣做當(dāng)然沒問題,但一般來說,您會(huì)將模型的每個(gè)實(shí)例放置在相近對(duì)象的較大集合中,比如 ArrayController(后面會(huì)詳細(xì)介紹)。

#p#

Views(視圖)

在一個(gè) Ember 應(yīng)用程序或任何 MVC 風(fēng)格的應(yīng)用程序中,View(視圖)是用戶可以看見并與之交互的組件。 通過將原始 HTML 直接添加到頁面,可以定義一個(gè)內(nèi)聯(lián)模板。 該模板將被包含在 script 標(biāo)記中。 您可以將它添加到頁面中您希望顯示內(nèi)容的任意位置。

  1. <script type="text/x-handlebars"> Hello <b>{{Songs.mixmaster}}</b> </script> 

請(qǐng)注意, script 標(biāo)記的類型是 text/x-handlebars 。 這使 Ember 在加載頁面時(shí),有一些東西可以抓取。 Ember 自動(dòng)準(zhǔn)備在這個(gè)腳本標(biāo)記內(nèi)所包含的任何 HTML,以便在您的應(yīng)用程序中使用。 將這幾行代碼放在您的應(yīng)用程序中,就會(huì)顯示以下文本:

  1. Hello <b>Andy</b> 

在繼續(xù)之前,先深入了解一下。 在您的瀏覽器中,右鍵單擊粗體文本,并使用瀏覽器的開發(fā)工具檢查它。 您可能注意到一些額外的元素。 為了知道在一個(gè)基本的屬性發(fā)生變化時(shí),要更新哪一部分的 HTML,Handlebars 將插入帶有唯一 ID 的標(biāo)記元素;例如:

  1. <b> <script id="metamorph-0-start" type="text/x-placeholder"></script> Andy <script id="metamorph-0-end" type="text/x-placeholder"></script> </b> 

您可以直接在 JavaScript 中定義一個(gè)視圖,然后使用視圖輔助程序?qū)⑺@示到頁面中。 Ember 有通用視圖,可以在應(yīng)用程序中創(chuàng)建簡單的 div 標(biāo)記,但它還配有預(yù)打包的一組視圖,用于構(gòu)建基本控件,比如文本輸入框、復(fù)選框和選擇列表。 從在 JavaScript 文件中定義簡單的 TextArea 視圖開始。

  1. Songs.ReviewTextArea = Ember.TextArea.extend({ placeholder: 'Enter your review' }); 

然后,通過引用包含該視圖的變量的、以單詞 view 開頭的路徑,將它顯示到頁面。 運(yùn)行下面的代碼,在您的瀏覽器中顯示 TextArea 字段,其占位符文本為 "Enter your review"。 您也可以在定義中指定 rows 和 cols 作為額外的屬性。

  1. <script type="text/x-handlebars"> {{view Songs.ReviewTextArea}} </script> 

Handlebars

現(xiàn)在,您可能想知道代碼中的 {{ 和 }} 表示什么,我們正好可以談?wù)?Handlebars,也稱為 mustaches。 稍微思考一下,您就會(huì)明白它們?yōu)槭裁幢环Q為 Handlebars pard'ner。 Handlebars 是一個(gè)模板引擎,讓開發(fā)人員可以混合原始 HTML 和 Handlebars 表達(dá)式 ,生成渲染的HTML。 表達(dá)式以 {{ 開始,并以 }} 結(jié)束。 如前所述,所有模板必須放在類型為 text/x-handlebars 的 script 標(biāo)記內(nèi)。

默認(rèn)情況下,handlebars 內(nèi)所包含的任何值據(jù)稱都會(huì)綁定到它的值。 這意味著,如果因?yàn)閼?yīng)用程序內(nèi)的一些其他操作使該值發(fā)生變化,顯示給用戶的值也將更新。 考慮以下代碼:

  1. <script type="text/x-handlebars"> My songs have {{Songs.totalReviews}} reviews. </script> 

第一次初始化您的應(yīng)用程序時(shí),用戶將看到以下文本。

  1. My songs have 0 reviews. 

但是,憑借數(shù)據(jù)綁定,隨著因更新 Songs.totalReviews 而添加的更多評(píng)論,該值將實(shí)時(shí)改變。

Handlebars 還通過使用 {{#if}}{{else}} . 支持流控制。 這些元素使您可以根據(jù)應(yīng)用程序中的值實(shí)現(xiàn)模板的 條件化 。 您可以修改前面的示例,在沒有任何評(píng)論時(shí)向用戶顯示另一條消息:

  1. <script type="text/x-handlebars"> {{#if Songs.totalReviews}} Read all my reviews! {{else}} There are no reviews right now. {{/if}} </script> 

如果在應(yīng)用程序的生命周期中的任意時(shí)點(diǎn), Songs.totalReviews 值發(fā)生了變化,該視圖將更新并顯示另一部分的消息。 值得注意的還有, # 和 / 符號(hào)只是為了告訴 Handlebars,這個(gè)特定的視圖輔助程序有一個(gè)閉合標(biāo)記。

Controllers(控制器)

此前,Model(模型)被定義為一種使開發(fā)人員能夠管理數(shù)據(jù)的方法。 這沒錯(cuò),但這只是一種狹義的定義。 一個(gè)模型只包含與單一事物有關(guān)的數(shù)據(jù);例如,一首歌曲(但不是多首歌曲)或一個(gè)人(但不是多個(gè)人)。 當(dāng)您想管理多個(gè)相同類型的數(shù)據(jù)塊時(shí),您需要一個(gè) Controller(控制器)。 有了 Ember,您可以使用 ArrayController 來管理多組歌曲、人員、部件或任何東西。 每個(gè) ArrayController 都有內(nèi)置的 content 屬性,用于存儲(chǔ)數(shù)據(jù)。 該數(shù)據(jù)可以是簡單的字符串,也可以是復(fù)雜的值,比如數(shù)組或?qū)ο蟆?此外,ArrayController 中包含的函數(shù)可以用于與在 ArrayController 中所包含的數(shù)據(jù)進(jìn)行交互。 您的 Song 集合的 ArrayController 看起來會(huì)是什么樣呢?

  1. Songs.songsController = Ember.ArrayController.create({ content: [], init: function(){ // create an instance of the Song model var song = Songs.Song.create({ title: 'Son of the Morning', artist: 'Oh, Sleeper', genre: 'Screamo' }); this.pushObject(song); } }); 

init 函數(shù)不是必需的,但它很方便,因?yàn)?songsController 一旦就緒,就會(huì)觸發(fā) init 函數(shù)。 它可以用來將現(xiàn)有數(shù)據(jù)填充到控制器,在本例中,您將使用它來將一首歌曲添加到控制器中,以演示 Ember 的數(shù)據(jù)綁定。 添加之前的 ArrayController 定義和以下內(nèi)聯(lián)模板,并在您的瀏覽器中運(yùn)行代碼:

  1. <script type="text/x-handlebars"> {{#each Songs.songsController}} <h3>{{title}}</h3> <p>{{artist}} - {{genre}}</p> {{/each}} </script> 

Handlebars each 輔助程序收到一組數(shù)據(jù)的路徑,然后對(duì)它進(jìn)行循環(huán)。 與控制器中每一項(xiàng)分別匹配的各個(gè) each 塊中的一切都將顯示在頁面上。 請(qǐng)注意,您沒有提供直接訪問內(nèi)容數(shù)組的路徑,因?yàn)榫?Ember 而言,控制器 就是 數(shù)組。所生成的 HTML 輸出如下所示:

  1. <h3>Son of the Morning</h3> <p>Oh, Sleeper - Screamo</p> 

全面整合: EmberTweets

此時(shí),您應(yīng)該已較好地了解了 Ember 是什么,以及它可以做什么。您也應(yīng)該了解使 Ember 實(shí)現(xiàn)其能力的每個(gè)組件: Application(應(yīng)用程序)、Model(模型)、View(視圖)和 Controller(控制器)。 現(xiàn)在是時(shí)候應(yīng)用這些知識(shí)了,以編寫一個(gè)真實(shí)可用的應(yīng)用程序。 您將跳過行業(yè)標(biāo)準(zhǔn)的 "todo 應(yīng)用程序" ,并轉(zhuǎn)移到對(duì)許多人來說更親近和熟悉的: Twitter。 在本教程的剩余部分,您將構(gòu)建一個(gè) Twitter 時(shí)間軸查看器。 在編寫任何代碼之前, 看看最終結(jié)果可能會(huì)有幫助。

#p#

創(chuàng)建樣板文件

使用本文開頭的樣板 HTML 頁面,您將首先構(gòu)建基礎(chǔ) HTML。 復(fù)制下面的代碼,并粘貼到一個(gè)名為 index.html 的新 HTML 文件中。您需要引用在本文的示例文件中的 CSS 文件。 示例文件還包含了這個(gè)項(xiàng)目的起點(diǎn),也可以供您隨時(shí)使用。

  1. <!doctype html> <html> 
  2. <head> 
  3. <title>Tweets</title> 
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
  5. <link rel="stylesheet" href="styles.css"> 
  6. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
  7. <script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.6.min.js"></script> 
  8. <script src="app.js"></script> 
  9. </head> 
  10. <body> 
  11. <script type="text/x-handlebars"> 
  12. <div id="frm"> <b>Load Tweets for: </b> </div>
  13. <div id="content"> 
  14. <div id="recent">
  15.  <h3>Recent Users</h3> 
  16. </div> 
  17. <div id="tweets"> <h3>Tweets</h3> </div> 
  18. </div>
  19.  </script>
  20.  </body>
  21.  </html> 

您可以看到這個(gè)應(yīng)用程序有三個(gè)部分: 一個(gè)輸入字段,允許用戶輸入一個(gè) Twitter 用戶名;時(shí)間軸查看器,顯示所選 Twitter 用戶的 tweet;以及最新的用戶列表,它將存儲(chǔ)以前的搜索。

搜索框?qū)⒊霈F(xiàn)在頁面頂部,最新的用戶在左側(cè)的欄中,而 tweet 本身將占據(jù)頁面右側(cè)的絕大部分版面。

下一步,創(chuàng)建名為 app.js 的另一個(gè)文件,并添加以下內(nèi)容。 這些注釋可以幫助您保持代碼的條理性。 在您的瀏覽器中加載此頁面,并確保沒有任何錯(cuò)誤。

  1. /************************** * Application **************************/ 
  2. /************************** * Models **************************/ 
  3. /************************** * Views **************************/ 
  4. /************************** * Controllers **************************/ 

請(qǐng)注意,此行使用的不是 Ember.Application,而是 Em.Application。在可能要使用 "Em" 任何地方,您都可以使用 "Ember",Ember 團(tuán)隊(duì)通過加入這個(gè)方便的快捷方式,減少了要輸入的字?jǐn)?shù)。

接下來,您將添加 TextInput 視圖和提交按鈕。 直接在標(biāo)記為 "Views" 的注釋塊下面,放入以下代碼:

  1. App = Em.Application.create(); 

請(qǐng)注意,此行使用的不是 Ember.Application,而是 Em.Application。在可能要使用 "Em" 任何地方,您都可以使用 "Ember",Ember 團(tuán)隊(duì)通過加入這個(gè)方便的快捷方式,減少了要輸入的字?jǐn)?shù)。

接下來,您將添加 TextInput 視圖和提交按鈕。 直接在標(biāo)記為 "Views" 的注釋塊下面,放入以下代碼:

  1. App.SearchTextField = Em.TextField.extend({ insertNewline: function(){ App.tweetsController.loadTweets(); } }); 

 此塊從使用 App 名稱空間開始,然后擴(kuò)展 Ember 的其中一個(gè)預(yù)打包的視圖 TextField。 除了在 Views 內(nèi)允許任意屬性和函數(shù)之外,Ember 也提供了內(nèi)置的輔助函數(shù)。 那就是 insertNewLine() 函數(shù);每當(dāng)光標(biāo)在輸入框中,并且用戶在鍵盤上按 Enter/Return 鍵時(shí),就會(huì)執(zhí)行該函數(shù)。

創(chuàng)建模板塊

現(xiàn)在已定義了 TextField View,您將要添加相應(yīng)的視圖輔助代碼到 HTML 文件中。 切換到 index.html 并在顯示為 "Load Tweets for" 的行后面直接添加以下代碼。 請(qǐng)記住, {{}} 內(nèi)的任何代碼都是模板,并且將被 Ember 用于輸出數(shù)據(jù)。 此外,任何以單詞 view 開始的模板指的都是已經(jīng)在您的 JavaScript 代碼中定義過的視圖。

  1. {{view App.SearchTextField placeholder="Twitter username" valueBinding="App.tweetsController.username"}} <button {{action "loadTweets" target="App.tweetsController"}}>Go!</button> 

這部分的模板包含一個(gè)視圖輔助程序,以及一個(gè)帶有 {{action}} 輔助程序的按鈕標(biāo)記。 TextField View SearchTextField 以占位符文本開始,占位符文本是內(nèi)置在 HTML5 文本輸入字段中的一個(gè)屬性。 如果該字段為空, placeholder 屬性中的文本將被放進(jìn)輸入字段。 當(dāng)有人開始輸入時(shí),該值將消失。 Ember 使開發(fā)人員可以在其內(nèi)置視圖內(nèi)使用任何 HTML 5 標(biāo)準(zhǔn)屬性。

第二個(gè)屬性突出顯示 Ember 數(shù)據(jù)綁定的能力。 Ember 使用一組約定來幫助它確定您想完成什么。 視圖(一個(gè)模板或一個(gè) JavaScript 文件中的視圖)中以單詞 "Binding" (注意大寫字母)結(jié)尾的任何屬性,自動(dòng)為它前面的屬性設(shè)置綁定。 在本例中,Ember 將 App.tweetsController.username 的值綁定到輸入字段的 value 屬性。 每當(dāng)變量的內(nèi)容發(fā)生變化,輸入字段中的值將自動(dòng)更新,反之亦然。

{{action}} 使得更易于將功能添加到輸入驅(qū)動(dòng)的元素。 它有兩個(gè)選項(xiàng): 操作名稱和目標(biāo)。 兩者綜合起來,形成一個(gè) "路徑" ,指向 Ember 對(duì)象中所包含的函數(shù)。 在上面按鈕的示例中, "路徑" 將是 App.tweetsController.loadTweets() ,當(dāng)用戶在文本字段內(nèi)按 Enter 鍵時(shí),也會(huì)調(diào)用相同的函數(shù)。 在您的瀏覽器中加載 index.html,并單擊提交按鈕,或在輸入字段內(nèi)按 Enter 鍵。 如果您查看瀏覽器控制臺(tái),您就會(huì)看到一個(gè)錯(cuò)誤。 這是因?yàn)檫€沒有定義 App.tweetsController 。

準(zhǔn)備 Tweet 存儲(chǔ)對(duì)象

現(xiàn)在是定義 App.tweetsController 的好時(shí)機(jī)。 在 app.js 中的 Controllers 注釋塊后面添加以下代碼。您應(yīng)該已經(jīng)熟悉以下代碼。 名稱空間、ArrayController、內(nèi)容數(shù)組 —— 一切都在。 但這次您將會(huì)添加一個(gè)任意屬性 ( username ) 和一個(gè)函數(shù) ( loadTweets )。 在添加 ArrayController 之后,重新加載您的瀏覽器。 在輸入框中輸入一個(gè)單詞,然后單擊按鈕。 您會(huì)得到一個(gè)提示框,回顯您所鍵入的單詞。 您可以隨時(shí)刪除提示行。 您還將看到一個(gè)錯(cuò)誤,表明尚未定義 addUser 方法。

  1. App.tweetsController = Em.ArrayController.create({ c
  2. ontent: [], username: '', loadTweets: function() { 
  3. var me = this; var username = me.get("username"); 
  4. alert(username); 
  5. if ( username ) { 
  6. var url = 'http://api.twitter.com/1/statuses/user_timeline.json' url += '?screen_name=%@&callback=?'.fmt(me.get("username")); 
  7. // push username to recent user array App.recentUsersController.addUser(username); 
  8. } } }); 

仔細(xì)看看 loadTweets 函數(shù)的定義;它有一些陌生的代碼。 第一行為函數(shù)的其余部分設(shè)置一個(gè) 范圍 。 根據(jù)定義,范圍或 this 對(duì)于所有 Ember 對(duì)象來說都是當(dāng)前函數(shù),在本例中是 App.tweetsController 。 但是,在本教程中,稍后您可以將更多功能添加到 loadTweets 函數(shù)。 現(xiàn)在設(shè)置當(dāng)前范圍,有助于 Ember 理解您正在使用的上下文。

如前所述,Ember 提供了許多輔助函數(shù),使編寫應(yīng)用程序變得更容易,這些函數(shù)包括 get()set() 。 這兩個(gè)函數(shù)內(nèi)置在每個(gè) Ember 對(duì)象中,并提供對(duì)任何屬性或函數(shù)的快速訪問。 下一行使用當(dāng)前對(duì)象 App.tweetsController 的范圍,然后調(diào)用 get() 函數(shù),將您希望獲取其值的屬性的名稱傳遞進(jìn)去。 您可能會(huì)好奇,在開始時(shí)要使用的用戶名的值從哪里來。 請(qǐng)記住,Ember 的數(shù)據(jù)綁定是雙向的。 這意味著,一旦您在輸入字段中鍵入了一個(gè)值,該輸入字段視圖的 valueBinding 屬性就會(huì)用一個(gè)值更新 App.tweetsController 對(duì)象。

檢索到用戶名后,會(huì)運(yùn)行一個(gè)測試,以確保它不是空的。 此時(shí) if 塊內(nèi)只有兩個(gè)語句,但這在以后會(huì)更改。 第一個(gè)語句為一個(gè)用戶將 URL 設(shè)置到 Twitter 的 JSON 文件。 您可能沒有馬上注意到這里有什么特殊之處,但仔細(xì)再看看,您就會(huì)發(fā)現(xiàn)末尾的 %@.fmt() 。 .fmt() 函數(shù)執(zhí)行一個(gè)方便的字符串替換,使用 %@ 作為標(biāo)記。 由于應(yīng)用程序的設(shè)計(jì)要求存儲(chǔ)搜索列表,因此您必須以某種方式存儲(chǔ)您的搜索字詞。 最后一行執(zhí)行該函數(shù),將用戶名的值推送到 App.recentUsersController ArrayController。 因?yàn)樵搶?duì)象尚未存在,所以運(yùn)行代碼將產(chǎn)生一個(gè)錯(cuò)誤。

#p#

存儲(chǔ)之前的搜索

在下面這一節(jié)中,您將創(chuàng)建用于存儲(chǔ)最近搜索的對(duì)象。 使用以下代碼并將它添加到 App.tweetsController 對(duì)象后面。

  1. App.recentUsersController = Em.ArrayController.create({ 
  2. content: [], addUser: function(name) { 
  3. if ( this.contains(name) ) 
  4. this.removeObject(name);
  5.  this.pushObject(name); }, removeUser: function(view)
  6. { this.removeObject(view.context); }, searchAgain:
  7.  function(view){ App.tweetsController.set('username', view.context); App.tweetsController.loadTweets(); },
  8.  reverse: function(){ return this.toArray().reverse(); }.property('@each') }); 

您已經(jīng)熟悉了如何創(chuàng)建 ArrayController 和添加一個(gè)空的內(nèi)容數(shù)組,但該對(duì)象有一些新的元素,它們以 addUser 函數(shù)開始。 這將使用名稱為 contains() 的內(nèi)置 Ember 函數(shù)檢查現(xiàn)有數(shù)組 ( this )。 如果它找到一個(gè)結(jié)果,它會(huì)使用 ArrayController 的函數(shù) removeObject() 刪除該結(jié)果。 與該函數(shù)相反,有一個(gè)名為 pushObject() 的函數(shù),它用于將單獨(dú)的對(duì)象添加到內(nèi)容數(shù)組。 這兩個(gè)函數(shù)都有處理多個(gè)對(duì)象的復(fù)數(shù)版本: pushObjects() 和 removeObjects() 。 此代碼在添加搜索詞之前首先刪除現(xiàn)有搜索詞,那么相同的搜索詞就不會(huì)被多次顯示。 既然您已經(jīng)知道如何從內(nèi)容數(shù)組中刪除一個(gè)對(duì)象, removeUser() 函數(shù)中唯一的新元素就是參數(shù)。 當(dāng)使用 {{action}} 輔助程序調(diào)用一個(gè)函數(shù)時(shí),Ember 隱式傳遞一個(gè)引用給當(dāng)前視圖。 在 App.tweetsController 的示例中,視圖有一個(gè)上下文,這基本上是當(dāng)前被遍歷的項(xiàng)。 該上下文用于從數(shù)組中刪除選定的項(xiàng)。

searchAgain() 函數(shù)也將當(dāng)前視圖接收為一個(gè)參數(shù)。 當(dāng)用戶單擊之前搜索過的字詞,該函數(shù)會(huì)用選定的用戶名填充 App.tweetsController.username ,然后觸發(fā) loadTweets() 函數(shù),為前面的搜索提供一個(gè)單擊視圖。

默認(rèn)情況下,Ember 按升序?qū)?nèi)容顯示到頁面。 數(shù)組索引 1 是第一個(gè),數(shù)組索引 2 是第二個(gè),依次類推。 此應(yīng)用程序的設(shè)計(jì)要求按降序顯示最近的搜索。 這意味著該數(shù)組必須被逆轉(zhuǎn)。 雖然這不是內(nèi)置函數(shù),但您可以看到要添加它是多么容易。 Reverse() 首先使用 Ember toArray() 函數(shù)將 Ember 內(nèi)容數(shù)組轉(zhuǎn)換成一個(gè)普通的數(shù)組,逆轉(zhuǎn)它,然后返回它。 使得該函數(shù)可以被用作一個(gè)數(shù)據(jù)源的,是在末尾添加的 property() 函數(shù)。 property() 函數(shù)使用一個(gè)指定函數(shù)所要求的以逗號(hào)分隔的屬性列表。 在本例中, property() 函數(shù)隱式地使用內(nèi)容數(shù)組本身,使用 @each 依賴鍵對(duì)該數(shù)組內(nèi)每個(gè)元素進(jìn)行尋址。 在下一節(jié)中,您將看到如何實(shí)施 reverse() 函數(shù)。

顯示之前的搜索

現(xiàn)在,您已存儲(chǔ)了之前的搜索,是時(shí)候?qū)⑺鼈冿@示在頁面上。 復(fù)制以下模板,并將它添加到標(biāo)簽為 Recent Users 的 h3 標(biāo)記后面。

  1. <ol> {{#each App.recentUsersController.reverse}} <li> <a href="#" title="view again" {{action "searchAgain" target="App.recentUsersController"}}>{{this}}</a> - <a href="#" title="remove" {{action "removeUser" target="App.recentUsersController"}}>X</a> </li> {{/each}} </ol> 

現(xiàn)在,您應(yīng)該已經(jīng)熟悉所有這些代碼。 each 塊指向內(nèi)容數(shù)組,它內(nèi)部所包含的 HTML 將被應(yīng)用到 App.recentUsersController 變量中的每一項(xiàng)。 不必顯式指向內(nèi)容數(shù)組,但在本例中,該代碼指向 reverse 函數(shù),它以反序提供數(shù)據(jù)。 {{action}} 輔助程序讓用戶單擊每個(gè)錨標(biāo)記,并觸發(fā)指定的函數(shù)。 可能不太熟悉的唯一一個(gè)元素是 {{this}} 。 當(dāng)遍歷內(nèi)容數(shù)組時(shí),Ember 在 {{this}} 變量中保存對(duì)當(dāng)前索引的引用。 因?yàn)槊恳豁?xiàng)的值都只是一個(gè)字符串,您可以使用 {{this}} 直接輸出當(dāng)前項(xiàng)的值。 單擊 Twitter 用戶名,將再次加載該用戶的 tweet,而單擊這些 tweet 的名稱則將從 recentUsersController 刪除它們。

加載 tweet

保存搜索詞沒問題了,但實(shí)際執(zhí)行搜索又如何呢? 接下來,您將添加從 Twitter 檢索 JSON 包的片段,并將它顯示到頁面。 使用以下 Ember Model 并直接將它添加到標(biāo)簽為 Model 的注釋塊后面。 請(qǐng)記住,Ember Model 是它們將包含的數(shù)據(jù)是一個(gè)藍(lán)圖。

  1. App.Tweet = Em.Object.extend({ avatar: null, screen_name: null, text: null, date: null }); 

在 app.js 中,找到顯示為 App.recentUsersController.addUser(username); 的代碼行;并在它后面直接添加以下代碼:

  1. $.getJSON(url,function(data){ me.set('content', []); $(data).each(function(index,value){ var t = App.Tweet.create({ avatar: value.user.profile_image_url, screen_name: value.user.screen_name, text: value.text, date: value.created_at }); me.pushObject(t); }) }); 

如果您以前使用過 jQuery,您可能已經(jīng)使用過 .get() 函數(shù)來檢索數(shù)據(jù)。 .getJSON() 函數(shù)做同樣的事情,只是它將 JSON 包視作一個(gè)結(jié)果。 此外,它使用返回的 JSON 字符串,并將它轉(zhuǎn)換成可執(zhí)行的 JavaScript 代碼。 數(shù)據(jù)被檢索到之后,內(nèi)容數(shù)組被清空,刪除所有現(xiàn)有的 tweet。 下一行提取數(shù)據(jù)包,并將它封裝在一個(gè) jQuery 對(duì)象中,因此 .each() 方法可以循環(huán)所生成的 Tweets。 在 each 塊中,使用數(shù)據(jù)填充了 Tweet Model 的一個(gè)副本,然后將其推送到 ArrayController。

最后,您需要將以下顯示代碼添加到 index.html。直接復(fù)制并粘貼它到標(biāo)簽為 Tweetsh3 標(biāo)記后面。

  1. <ul> {{#each App.tweetsController}} <li> <img {{bindAttr src="avatar"}} /> <span>{{date}}</span> <h3>{{screen_name}}</h3> <p>{{text}}</p> </li> {{/each}} </ul> 

Ember 使用純 {{Handlebars}} 可以很容易地輸出數(shù)據(jù)到頁面,但有一個(gè)問題。 還記得 Ember 如何在腳本標(biāo)記中包裝輸出的值嗎? 當(dāng)您使用 HTML 屬性時(shí),這并不是一個(gè)選項(xiàng)。 所以 Ember 提供 {{bindAttr}} 輔助程序。 在這個(gè)輔助程序內(nèi)放置的任何屬性都將如常輸出,但仍保留綁定。 繼續(xù)進(jìn)行操作,現(xiàn)在運(yùn)行您的應(yīng)用程序。 輸入一個(gè)用戶名,會(huì)看到 Tweets 出現(xiàn)。

下一步閱讀方向

在本文中,您學(xué)習(xí)了 Ember.js 功能的基礎(chǔ)知識(shí)。 您也學(xué)習(xí)了 Ember 如何使用其Models、Views、Controllers,當(dāng)然還有 Application 對(duì)象實(shí)施 MVC。 您使用 Handlebars 通過視圖輔助程序和操作輔助程序創(chuàng)建了模板。 您學(xué)習(xí)了如何使用 Models 創(chuàng)建數(shù)據(jù)的藍(lán)圖,使用 Controllers 將該數(shù)據(jù)存儲(chǔ)在集合集,并使用 Views 將數(shù)據(jù)顯示到頁面。 最后,您使用了 Ember 來構(gòu)建一個(gè)具有數(shù)據(jù)綁定、計(jì)算屬性和自動(dòng)更新模板的完整應(yīng)用程序。 您的母親將為您感到自豪!

原文鏈接:http://www.adobe.com/cn/devnet/html5/articles/flame-on-a-beginners-guide-to-emberjs.html

責(zé)任編輯:陳四芳 來源: adobe.com
相關(guān)推薦

2013-12-24 15:56:20

2013-12-24 11:11:27

ember.jsJavascript

2013-12-24 16:03:26

Ember.js視圖

2024-04-28 10:56:34

Next.jsWeb應(yīng)用搜索引擎優(yōu)化

2022-04-24 15:21:01

MarkdownHTML

2022-10-10 15:28:45

負(fù)載均衡

2010-06-13 11:13:38

UML初學(xué)者指南

2022-07-22 13:14:57

TypeScript指南

2021-05-10 08:50:32

網(wǎng)絡(luò)管理網(wǎng)絡(luò)網(wǎng)絡(luò)性能

2022-03-28 09:52:42

JavaScript語言

2023-07-28 07:31:52

JavaScriptasyncawait

2023-07-03 15:05:07

預(yù)測分析大數(shù)據(jù)

2010-08-26 15:47:09

vsftpd安裝

2018-10-28 16:14:55

Reactreact.js前端

2013-12-24 14:50:39

Ember.js框架

2012-03-14 10:56:23

web app

2023-02-10 08:37:28

2022-09-05 15:36:39

Linux日志記錄syslogd

2015-06-30 08:41:55

Node.js指南

2024-12-25 08:00:00

機(jī)器學(xué)習(xí)ML管道人工智能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)