摘要:由于能力有限本示例不會完全自定義適配器和序列化器,示例仍然是使用官方推薦方式,重寫或者擴展以實現自定適配器和序列化器。在序列化器中調用響應請求的方法格式化返回的數據。上述就是的一個簡單實用示例。
文章來源:http://xcoding.tech/tags/Emberjs
歡迎訪問源網站Ember Teach,Ember Teach致力于為您提供最權威、最前沿的Ember技術教程。。
adapter與serializer相對來說是比較高級的內容。但是也是非常常用的一個組件,最常用到這兩個組件的就是Ember Data。Ember Data已經實現了這兩個組件,并且提供了非常豐富的API,如果要自定義適配器和序列化器一般都是擴展或者是重寫JSONAPIAdapter,這也是官方建議的方式,JSONAPIAdapter是遵循json api規范的適配器,主要表現在數據的交換格式必須遵循JSONAPI規范。當然如果你想完全重新實現一套自定義的適配器和序列化器也是可以的,官方建議是基于Adapter做擴展。由于能力有限本示例不會完全自定義適配器和序列化器,示例仍然是使用官方推薦方式,重寫或者擴展JSONAPIAdapter以實現自定適配器和序列化器。
那么我們為何需要自定義適配器呢?很明顯的一個原因就是Ember.js并沒有提供數據存儲方案,Ember目前更多的只是一個前端的MVC框架,數據的存儲服務還是要開發者提供,目前比較流行的做法是使用谷歌的Firebase,Firebase是一個實時更新數據的后端服務,國內也有類似的跟隨者(野狗)但是目前野狗還沒有Ember的適配器,相反Firebase提供了完備的Ember適配器,使用起來非常方便,而且還提供了免費的服務。可以說除了網速比較慢之外是非常適合做Ember的數據服務的。但是比較遺憾的是我們在天朝內,你懂滴,谷歌的東西在我們這個國度要使用還是不怎么順暢的。那么既然不能使用現有的輪子那么我們只能使用自己的后端數據服務了,此時就必須要自定義適配器了(我們能直接使用Firebase的原因就是Firebase提供完美的適配器,不需要開發者去開發,直接使用即可)。
Ember所推崇是“約定由于配置”,所有Ember默認了很多規則,自然適配器和序列化器也不例外,所以本例子程序會包括兩個方面的東西,一個是Ember項目本身;另一個是為Ember項目提供服務器的后端數據庫以及數據庫處理程序。
主要軟件說明MongoDB
NodeJS
Mongoose
json api服務端
Ember CLI
上述軟件的安裝與配置請自行根據各自官網文檔介紹安裝配置,如果你想使用其他數據庫也是可以的,但是處理起來可能沒有MongoDB那么方便,如果你看過jsonapi規范就知道,jsonapi相對于普通的json數據還是有挺大差別的,如果是使用其他數據庫(比如MySQL)處理起來可能稍微麻煩一些,另外一個很重要的原因就是json API插件大部分都是node版的,說了這么多其實就是想把服務器返回的數據格式格式化為jsonapi規范,否則其他格式的數據JSONAPIAdapter適配器是無法識別的,會報錯。
再啰嗦幾句:一個APP之所以能與后端服務良好交互,其他交互的數據格式都是比較固定的,Ember也不例外,因為Ember Data所接受的數據格式是jsonapi,所以我們的后端服務返回的數據格式必須符合jsonapi規范,當然如果你不是使用Ember Data,你使用的是其他的數據持久化庫也是可以的,那么相對的你的的后端數據服務返回的數據格式就要跟你的持久化庫相匹配就可以了,如果你想使用其他的持久化庫你可以參考jsonapi client libraries,上面提供了各個語言的持久化庫。
搭建項目言歸正傳,下面結合一個小例子講解如何去自定義適配器去連接到自己的數據庫,并把數據持久化到數據庫中。
使用Ember CLI創建一個普通的Ember項目,命令如下:
ember new ember-adapter-serializer cd ember-adapter-serializer ember s
啟動項目后預覽http://localhost:4200,可以看到Ember常規的歡迎信息,說明項目創建成功。
創建路由、模型、模板仍然是使用Ember CLI命令創建演示示例所需的路由、模型、模板文件,本示例會構建一個簡單的博客項目,目的主要是為了使項目盡量包含模型的一對一、一對多、多對多關系,這些關系是一個適配器比較關鍵的東西(簡單理解,其實適配器就像MVC項目中的DAO層,專門做數據處理的)。
創建命令如下:
ember g route users ember g model user ember g route users/list ember g route users/new ember g route users/edit ember g route posts ember g model post ember g route tags ember g model tag ember g route comments ember g model comment
后續使用到其他的文件再創建。
模型處理模型的處理主要是設置模型的屬性以及模型之間的關系,在本例子中定義了3個模型:user、post、tag、comment。他們的關系如下:
user與post是一對多的關系
user與comment是一對多的關系
post與comment也是一對多的關系
post與tag是多對多關系
各個模型代碼如下:
user// app/models/user.js import Model from "ember-data/model"; import attr from "ember-data/attr"; import { belongsTo,hasMany } from "ember-data/relationships"; export default Model.extend({ name: attr("string"), password: attr("string"), birth: attr("string"), addr: attr("string"), //一對多關系,一的一方設置hasMay,多的一方設置belongsTo comments: hasMany("comment"), posts: hasMany("post") });post
// app/models/post.js import Model from "ember-data/model"; import attr from "ember-data/attr"; import { belongsTo,hasMany } from "ember-data/relationships"; export default Model.extend({ title: attr("string"), publicDate: attr("date"), content: attr("string"), user: belongsTo("user"), //一對多關系,多的一方使用belongsTo comments: hasMany("comment"), tags: hasMany("tag") });comment
// app/models/comment.js import Model from "ember-data/model"; import attr from "ember-data/attr"; import { belongsTo,hasMany } from "ember-data/relationships"; export default Model.extend({ title: attr("string"), publicDate: attr("date"), content: attr("string"), user: belongsTo("user"), //一對多關系,多的一方使用belongsTo post: belongsTo("post") });tag
// app/models/tag.js import Model from "ember-data/model"; import attr from "ember-data/attr"; import { belongsTo,hasMany } from "ember-data/relationships"; export default Model.extend({ title: attr("string"), posts: hasMany("post") });
創建完模型之后,先從user開始,簡單做一個列表顯示所有user,并在在列表頁面可以新增、修改、刪除user,實現最常見的CRUD操作。在實現的過程中插入adapter和serializer的內容。
用戶列表用戶列表頁面也是很簡單的,就一個表格,其中引入了bootstrap樣式。有關怎么引入請自己網上找答案吧。
列表模板{{! app/templates/users/list.hbs 用戶列表}}列表路由配置{{#link-to "users.new" class="btn btn-success"}}新增{{/link-to}}
{{#each model as |user|}} 用戶名 生日 地址 操作 {{/each}} {{user.name}} {{user.birth}} {{user.addr}} {{#link-to "users.edit" user.id}}修改{{/link-to}} | 刪除
import Ember from "ember"; export default Ember.Route.extend({ model() { return this.store.findAll("user"); } });
列表的路由也很簡單,直接獲取所有的user記錄,并返回到模板中,在模板中便利出每個記錄。
待項目重啟完成,直接預覽http://localhost:4200/users/list,可以看到頁面上什么也沒有顯示,打開瀏覽器控制臺可以看到如下錯誤:
很顯然我們的項目中確實沒有提供請求http://localhost:4200/users的后端服務,而且項目也沒有鏈接其他任何數據服務(比如Firebase),那么如何讓Ember項目鏈接到我自己的數據庫上呢?
在此,先引入數據服務程序,前面介紹過,本例子使用Mongodb。服務端程序請看adapter-serializer-server,對于服務端的內容我就部過多介紹,你只需要知道這個服務程序可以接受、返回的數據格式是jsonapi就行了。然后啟動后端服務程序。
那么如何讓Ember項目鏈接到我的后端服務呢??很簡單,只需要重寫適配器的一個屬性即可。下面使用Ember CLI名稱創建一個適配器。
ember g adapter application
適配器創建完畢之后,我們直接在適配器中接入自己的后端服務。代碼如下:
// app/adapters/application.js import JSONAPIAdapter from "ember-data/adapters/json-api"; export default JSONAPIAdapter.extend({ host: "http://localhost:3000" });
http://localhost:3000是adapter-serializer-server啟動后提供服務的url。項目啟動完畢后可以看到瀏覽器控制臺的錯誤消失了!并且在“NetWork”標簽下可以看到有一個請求http://localhost:3000/users點擊這個請求,查看請求的“Response”可以看到返回的數據,比如下面的數據格式:
{ "links": { "self": "http://localhost:3000/users" }, "data": [ { "id": "5753d7090280777c2381a0dd", "type": "users", "attributes": { "name": "日期修改333", "password": "11", "addr": "地址地址地址地址", "birth": "2016-06-04T00:00:00.000Z" }, "links": { "self": "http://127.0.0.1:3000/users/5753d7090280777c2381a0dd" }, "relationships": { "comments": { "data": [], "links": { "self": "http://127.0.0.1:3000/users/5753d7090280777c2381a0dd/relationships/comments" } }, "posts": { "data": [], "links": { "self": "http://127.0.0.1:3000/users/5753d7090280777c2381a0dd/relationships/posts" } } } }, { "id": "5753d74a840db09d2352608a", "type": "users", "attributes": { "name": "解決了跨域問題", "password": "123132", "addr": "范文芳啊的份水電費 測試服我飛" }, "links": { "self": "http://127.0.0.1:3000/users/5753d74a840db09d2352608a" }, "relationships": { "comments": { "data": [], "links": { "self": "http://127.0.0.1:3000/users/5753d74a840db09d2352608a/relationships/comments" } }, "posts": { "data": [], "links": { "self": "http://127.0.0.1:3000/users/5753d74a840db09d2352608a/relationships/posts" } } } }, { "id": "57545597840db09d2352608b", "type": "users", "attributes": { "name": "測試日期控件", "password": "123123", "addr": "適配器和序列化器示例" }, "links": { "self": "http://127.0.0.1:3000/users/57545597840db09d2352608b" }, "relationships": { "comments": { "data": [], "links": { "self": "http://127.0.0.1:3000/users/57545597840db09d2352608b/relationships/comments" } }, "posts": { "data": [], "links": { "self": "http://127.0.0.1:3000/users/57545597840db09d2352608b/relationships/posts" } } } } ] }
由于我項目已經有了3條數據了,所以跟你的可能有些許不同,但是數據的格式是一致的。這個數據的格式是遵循jsonapi規范的。
上述代碼所演示的是自定義適配器最最常用的一個功能,如果你后端返回的數據是完全遵循jsonapi規范的幾乎不需要再做其他任何修改了。這樣就已經完成自定義適配器的工作了!但是既然在此特意介紹適配器和序列化器當然不會只是介紹這一個屬性host就完了,后面將陸陸續續介紹其他的屬性,以及如何使用serializer。
繼續完成user模塊。
新增user user模板{{! app/templates/users/new.hbs 新增user}}user路由
直接在model回調中返回一個空的實例對象。方便保存。
// app/routes/users/new.js import Ember from "ember"; export default Ember.Route.extend({ model() { return this.store.createRecord("user"); }, actions: { saveUser(user) { user.save().then(() => { this.transitionTo("users.list");// 保存成功轉到列表頁面 }); } } });修改user user模板
{{! app/templates/users/edit.hbs 修改user}}user路由
在修改的方法中先調用findRecord方法查詢出被修改的數據,然后更新修改的屬性,再調用save方法保存修改的內容。
// app/routes/users/edit.js import Ember from "ember"; export default Ember.Route.extend({ // 根據ID查詢 model(params) { return this.store.findRecord("user", params.user_id); }, actions: { updateUser(user) { this.store.findRecord("user", user.get("id")).then((u) => { u.set("name", user.get("name")); u.set("addr", user.get("addr")); u.set("birth", user.get("birth")); u.set("addr", user.get("addr")); u.save(); //保存修改的屬性值 }); this.transitionTo("users.list"); //轉到列表頁面 } } });
由于新增、修改user模板都用到供一個表單,提取到一個組件中。
ember g component user-form
文件代碼就不貼出來了,有需要請點擊查看github代碼。然后在組件類中初始化了一個日期控件bootstrap-datepicker,插件直接在app/index.html中引入了,下面是組件類代碼:
// app/components/user-form.js import Ember from "ember"; export default Ember.Component.extend({ didInsertElement() { this._super(...arguments); //記得調用父類的構造方法 //初始化日期控件 Ember.$(".datepicker").datepicker({format:"yyyy-mm-dd", autoclose: true}); } });
user列表、新增user、修改user界面效果如下截圖:
到此實現了類似使用Firebase的數據存儲功能,可以正確保存數據到自己的數據庫中。可以肯定的是數據已經正確保存到我的MongoDB中,我就不再截圖了!對象的CRUD功能已經實現,后續我就不再介紹post、comment、tag的CRUD了,后續著重介紹適配器、序列化器的其他屬性以及模型之間的關聯關系(比如一對多、多對多)。
如果你認真看前面的第一個截圖你會發現列表上顯示的時間格式不友好,不是我們所習慣看的時間格式,那么如何處理呢?格式化時間的方式有很多,可以自定義Ember helper格式化時間,也可以定義模型user的屬性birth為date類型,在此我特意定義為了string是為了演示serializer的使用。我們可以在自定義的serializer中格式化返回的數據。下面首先創建serializer。
ember g serializer application
在序列化器中調用響應請求的方法normalizeResponse格式化返回的數據。代碼如下:
// app/serializers/application.js import JSONAPISerializer from "ember-data/serializers/json-api"; export default JSONAPISerializer.extend({ // 此方法響應請求的時候執行 normalizeResponse(store, primaryModelClass, payload, id, requestType) { // 格式化birth的時間格式 //默認顯示的時間格式為 2016-06-09T00:00:00.000Z ,簡單處理直接截取前面的10位 // 只是為了演示方法normalizeResponse的使用,實際項目中不推薦這樣的用法,因為需要遍歷每個數據,效率不好 payload.data.forEach(function(item, index) { var oldDate = item.attributes.birth; if (oldDate) { oldDate = oldDate.substring(0, 10); } item.attributes.birth = oldDate; oldDate = null; }); return this._super(...arguments); } // 此方法發送請求的時候回執行 // serialize(snapshot, options) { // // } });
但是實際使用過程中不推薦使用這種方式格式化數據,除非是不得已,因為需要遍歷每個記錄去修改屬性的值,如果數據量大影響效率,最好的方式是自定義helper在模板上格式化。把格式化的操作放到顯示數據的時候。
上述就是serializer的一個簡單實用示例。
adapter和serializer內容比較多,分為2篇介紹,下一篇我回在本篇的基礎上逐個介紹adapter和serializer的常用屬性、方法的使用。
adapter與serializer使用下篇adapter與serializer使用實例二
項目源碼:https://github.com/ubuntuvim/ember-adapter-serializer
后臺源碼:https://github.com/ubuntuvim/adapter-serializer-server
有疑問歡迎在下方評論區給我留言,我會盡快為你解答,如果你覺得本文能給你幫助,或者覺得博主寫作辛苦也歡迎點擊右上角“為博主充電”給我打賞,你的肯定對我來說是最大的動力。O(∩_∩)O哈哈~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86351.html
摘要:返回數據請求流程后端返回的數據首先也會經過上面的處理其次經過返回進將數據存儲起來后返回請求數據的地方。至此一個請求后端數據的請求的流程就到此結束了。例如等以及官方推薦最少要復寫的方法 Emberjs 如何與后端服務進行交互 @[toc] 一般發送請求流程 首先來看這張圖: showImg(https://segmentfault.com/img/bVCzJn?w=339&h=521...
摘要:目前打算本項目使用種數據交互方式一種是,一種是。要理解后端服務的關系我們從他們各自的概念入手。創建服務端如何在項目中創建服務端程序呢提供了創建的命令。 文章來源:Ember Teach 本項目講解如何使用adapter、EmberData以及怎么連接到本地數據庫。 項目簡介 主要內容 適配器使用 如何持久化數據到本地數據庫 簡單的后端服務 最近經常有初學的開發者請教有關Adapte...
摘要:就沒必要動牛刀,創建一個數據庫了執行完后,在目錄下創建一個程序,自動植入到當前項目中,訪問的和與訪問域名端口一致。就沒必要動牛刀,創建一個數據庫了本篇博文將為你介紹如何使用實現權限控制,我會創建一個簡單的登錄示例加以說明。 文章來源:http://blog.ddlisting.com 官網對于登錄、用戶權限的介紹只有一段簡單的說明,并沒有詳細說明如何使用service實現權限控制。下面...
摘要:遠程調用開篇目標介紹之后解讀遠程調用模塊的內容如何編排介紹中的包結構設計以及最外層的的源碼解析。十該類就是遠程調用的上下文,貫穿著整個調用,例如調用,然后調用。十五該類是系統上下文,僅供內部使用。 遠程調用——開篇 目標:介紹之后解讀遠程調用模塊的內容如何編排、介紹dubbo-rpc-api中的包結構設計以及最外層的的源碼解析。 前言 最近我面臨著一個選擇,因為dubbo 2.7.0-...
閱讀 3444·2021-09-08 10:46
閱讀 1180·2019-08-30 13:17
閱讀 2358·2019-08-30 13:05
閱讀 1200·2019-08-29 15:29
閱讀 2882·2019-08-29 11:31
閱讀 533·2019-08-26 12:13
閱讀 1532·2019-08-26 11:42
閱讀 1818·2019-08-23 18:37