我希望您開始認識到 Ember.js 是一個強大但固執己見的框架。我們只觸及了它的表面;在我們建造真正有用的東西之前,還有更多東西需要學習!我們將繼續使用 Ember 入門套件。在本系列的這一部分中,我們將回顧如何存取和管理 Ember 中的資料。
在上一篇文章中,我們使用了在控制器中定義的一組靜態顏色名稱:
App.IndexRoute = Ember.Route.extend({ setupController: function(controller) { controller.set('content', ['red', 'yellow', 'blue']); } });
這允許控制器將資料公開給索引範本。這對於演示來說很可愛,但在現實生活中,我們的資料來源不會是硬編碼的陣列。
這就是模型的用武之地。模型是應用程式使用的資料的物件表示。它可以是一個簡單的陣列或從 RESTful JSON API 動態檢索的資料。透過引用模型的屬性來存取資料本身。因此,如果我們看一下這樣的結果:
{ "login": "rey", "id": 1, "age": 45, "gender": "male" }
模型中公開的屬性是:
透過引用模型的屬性來存取資料本身。
正如您從上面的程式碼中看到的,您可以定義一個靜態存儲,但大多數時候您將使用 Ember.Object 來定義模型。透過子類化 Ember.Object
,您將能夠傳回資料(例如:透過 Ajax 呼叫)並定義您的模型。雖然您可以在控制器中明確設定數據,但始終建議您建立一個模型,以便遵守關注點分離和程式碼組織最佳實踐。
或者,您可以使用名為 Ember Data 的姊妹框架。它是一個類似 ORM 的 API 和持久性存儲,但我需要強調的是,在撰寫本文時它正處於不斷變化的狀態。它有很大的潛力,但此時使用 Ember.Object
更安全。 Discourse 的聯合創始人 Robin Ward 撰寫了一篇關於在沒有 Ember 數據的情況下使用 Ember 的精彩部落格文章。它概述了他們的流程,我將為您分解。
在下面的範例中,我將使用非官方的 Hacker News API 從新聞資源中提取基於 JSON 的資料。該數據將儲存在我的模型中,稍後由控制器用來填充模板。如果我們查看從 API 傳回的數據,我們就可以了解我們將使用的屬性:
{ "nextId": null, "items": [{ "title": "Docker, the Linux container runtime: now open-source", "url": "http://docker.io", "id": 5445387, "commentCount": 39, "points": 146, "postedAgo": "2 hours ago", "postedBy": "shykes" }, { "title": "What\u0027s Actually Wrong with Yahoo\u0027s Purchase of Summly", "url": "http://hackingdistributed.com/2013/03/26/summly/", "id": 5445159, "commentCount": 99, "points": 133, "postedAgo": "2 hours ago", "postedBy": "hoonose" }, ], "version": "1.0", "cachedOnUTC": "\/Date(1364333188244)\/" }
我想使用 items
屬性,其中包含所有標題和故事資訊。如果您使用過SQL 資料庫,請將items
的每個元素視為一筆記錄,並將屬性名稱(即:title
、url
、id
等)視為欄位名稱。理解佈局很重要,因為這些屬性名稱將用作模型物件的屬性,這是創建模型的完美銜接。
Ember.Object
是所有 Ember 物件的主要基類,我們將對其進行子類化以使用其extend()
方法建立我們的模型。
為此,我們將在定義 App.IndexRoute
的程式碼之後立即將以下程式碼加入 js/app.js 中:
App.Item = Ember.Object.extend();
App.Item
用作駭客新聞資料的模型類,但它沒有檢索或操作該資料的方法。因此,我們需要定義這些:
App.Item.reopenClass({ all: function() { return $.getJSON("http://api.ihackernews.com/page?format=jsonp&callback=?").then(function(response) { var items = []; response.items.forEach( function (item) { items.push( App.Item.create(item) ); }); return items; }); } });
讓我們分解這段程式碼。首先,我們使用 Ember 的 reopenClass()
方法將新方法加入 App.Item
類別中,然後傳遞一個包含我們所需方法的物件。對於此範例,我們只需要一個名為 all()
的方法:它會傳回駭客新聞首頁的所有標題。因為 jQuery 是 Ember 協定的一部分,所以我們可以使用它簡單的 Ajax API。 API使用JSONP傳回JSON資料;所以,我可以使用 $.getJSON()
向以下位置發出請求:
$.getJSON("http://api.ihackernews.com/page?format=jsonp&callback=?")
「回呼=?」告訴 jQuery 這是一個 JSONP 請求,並且資料(一旦檢索到)將傳遞到使用 jQuery 的 Promise 功能定義的匿名回呼處理程序:
.then(function(response) {...});
我可以輕鬆地將 JSON 資料注入 Ember 物件。
response
參數包含 JSON 數據,讓您可以循環記錄並使用 App.Item
的實例更新本地 items
數組。最後,當 all()
執行時,我們會傳回新填入的陣列。說了這麼多,我總結一下:
extend()
子类化 Ember.Object
来创建新模型类。reopenClass()
添加模型方法。Item
对象并将其推入数组中。如果您刷新index.html,您将看到没有任何变化。这是有道理的,因为模型刚刚被定义;我们还没有访问过它。
控制器的作用类似于代理,使您可以访问模型的属性并允许模板访问它们以便动态渲染显示。除了从关联模型访问属性之外,控制器还可以存储需要持久保存的其他应用程序属性,而无需保存到服务器。
目前,我们的应用程序具有以下控制器(定义静态数据集的控制器):
App.IndexRoute = Ember.Route.extend({ setupController: function(controller) { controller.set('content', ['red', 'yellow', 'blue']); } });
我们可以使用 model
方法(又名模型钩子)直接将我们的模型与 App.IndexRoute
关联起来:
App.IndexRoute = Ember.Route.extend({ model: function() { return App.Item.all(); } });
请记住,如果您自己没有显式定义控制器,那么 Ember 会定义您的控制器,这就是本例中发生的情况。
在幕后,Ember 创建
IndexController
作为Ember.ArrayController
的实例,并使用model
方法中指定的模型。
现在我们只需要更新索引模板即可访问新属性。打开index.html,我们可以看到以下Handlebars模板代码:
{{#each item in model}} <li>{{item}}</li> {{/each}}
通过一个小更改(添加 title
属性),我们可以立即看到从 Hacker News API 返回的标题:
{{item.title}}
如果您现在刷新浏览器,您应该会看到类似以下内容的内容:
<h3>Welcome to Ember.js</h3> <ul><li>Persona is distributed. Today.</li> <li>21 graphs that show America's health-care prices are ludicrous</li> <li>10 000 concurrent real-time connections to Django</li> <li>Docker, the Linux container runtime: now open-source</li> <li>Let's Say FeedBurner Shuts Down…</li></ul>
如果您想显示更多信息,只需添加更多属性:
{{item.title}} - {{item.postedAgo}} by {{item.postedBy}}
刷新即可查看您所做的更新。这就是 Handlebars 的魅力所在;它使得向用户界面添加新数据元素变得微不足道。
正如我之前提到的,控制器还可以用于定义需要在应用程序的整个生命周期中保留的静态属性。例如,我可能想保留某些静态内容,如下所示:
App.IndexController = Ember.ObjectController.extend({ headerName: 'Welcome to the Hacker News App', appVersion: 2.1 });
在这里,我将 Ember.ObjectController
子类化,为我的 index 路由和模板创建一个新的控制器。我现在可以转到 index.html 并更新我的模板以替换以下内容:
<h2>Welcome to Ember.js</h2>
与:
<h2>{{headerName}}</h2>
模型是应用程序使用的数据的对象表示。
Handlebars 将采用我的控制器中的指定属性,并用其同名值动态替换 {{headerName}}
占位符。强调两件事很重要:
IndexController
,Ember 也足够聪明,不会覆盖通过路由关联的现有模型。这是非常强大且灵活的东西!
在 Ember 中处理数据并不困难。实际上,最困难的部分是使用网络上大量的各种 API。
事实上,我可以轻松地将 JSON 数据输入到 Ember 对象中,这使得管理变得更加容易 — 尽管我从来都不是客户端大型数据集的忠实粉丝,尤其是当表示为对象时.
这是我必须做更多测试的事情,我希望 Ember Data 能让这一切变得微不足道。
话虽如此,我在本文中简要介绍了模板。它们非常重要……以至于我想在自己的文章中讨论这个主题。因此,在下一篇文章中,我们将介绍如何利用 Handelbars 构建用户界面,并深入了解模板框架提供的各种指令。
以上是進入Ember.js的第三部分:深入探索的詳細內容。更多資訊請關注PHP中文網其他相關文章!