摘要:默認使用,在我們的項目中也是使用所以只是涉及關于的相關內容。這樣來達到前后端通信的要求。這個方法可以在中定義特定的來針對調用。同理,其他的更新刪除相似至此的相關屬性與已解釋完成。
Ember Serializer
Emberjs 默認使用 JSONAPISerializer ,在我們的項目中也是使用JSONAPISerializer.所以只是涉及關于 JSONAPISerializer 的相關內容。
@[TOC]
在目前的版本中,后端我們使用 大駝峰法命名,但是前端基本使用都是 駝峰法,導致有所差異,在數據獲取展示過程中,需要統一 key 的名稱。這時就可以使用 keyForAttribute 這個方法來實現我們的需求,比如:
// 后端數據 { "data": [{ "type": "people", "id": "123", "attributes": { "FirstName": "Jeff", "LastName": "Atwood", "Birthday": new Date().getTime() } }, { "type": "people", "id": "124", "attributes": { "FirstName": "Yehuda", "LastName": "Katz", "Birthday": new Date("2011-11-11 11:11:11").getTime() } }] };
而在前端 我們定義的屬性名為:
// person/model.js import DS from "ember-data"; export default DS.Model.extend({ firstName: DS.attr("string"), lastName: DS.attr("string"), birthday: DS.attr("date") });
前端使用的是 常用的駝峰命名法,在這樣的情形下(前后端屬性名字不一致),我們就需要修改向后端申請的屬性名稱來將后端數據合理的傳遞到我們前端定義的屬性名上來:
// person/serializer.js import DS from "ember-data"; import { camelize, capitalize } from "@ember/string"; export default DS.JSONAPISerializer.extend({ keyForAttribute(key) { let newKey = camelize(key); return capitalize(newKey); } });
keyForAttribute 這個方法接受 前端 定義的屬性名稱為參數,如當下的firstName等,經過轉換為后端相同的屬性名,如FirstName 。這樣來達到前后端通信的要求。
前端 modelName 的變化在上面我們可以看到,后端返回數據中的 type為people,但是前端尋找的type 卻為person,這是因為 Ember Data 中的約定的關系,但是如果我們就想讓它尋找的type 為 people呢?那我們就需要用到 modelNameFromPayloadKey 這個方法:
// people/serilizer.js import DS from "ember-data"; import { camelize, capitalize } from "@ember/string"; export default DS.JSONAPISerializer.extend({ modelNameFromPayloadKey(key) { return key; }, keyForAttribute(key) { let newKey = camelize(key); return capitalize(newKey); } });
通過復寫這個方法就可以禁止 modelName 的單復數轉換了。
目前我們是在多帶帶的 model 下執行的這個 serializer 的幾個方法,如果需要在全局則需要將 serializer.js文件寫在 application 下1。
相應的,還會有payloadKeyFromModelName
## IDs
在 JSONAPI 中 每個條目都應該使用 id 中的值來作為為一標識,前后端都應如此,如果后端沒有將 id 作為唯一標識,那么就可以使用 primaryKey 這個屬性來定義一個唯一標識:
這是前端定義的:
// people/serilizer.js import DS from "ember-data"; import { camelize, capitalize } from "@ember/string"; export default DS.JSONAPISerializer.extend({ primaryKey: "pKey", modelNameFromPayloadKey(key) { return key; }, keyForAttribute(key) { let newKey = camelize(key); return capitalize(newKey); } });
而后端傳來的數據即可變更為:
// 后端數據 { "data": [{ "type": "people", "pKey": "123", "attributes": { "FirstName": "Jeff", "LastName": "Atwood", "Birthday": new Date().getTime() } }, { "type": "people", "pKey": "124", "attributes": { "FirstName": "Yehuda", "LastName": "Katz", "Birthday": new Date("2011-11-11 11:11:11").getTime() } }] };縮短屬性名
在日常工作中的難題之一就是命名,而往往后端的命名和前端的不太一致,如果我們做了大量的展示工作,再更換名稱那就有點比較麻煩,這時候我們可以使用 attrs屬性來達到我們的目的:
后端傳輸的數據中有一:
// ... ThePersonSelfHeight:176 // ...
前端認為這個名字過于復雜所以想alias:
// people/serilizer.js import DS from "ember-data"; export default DS.JSONAPISerializer.extend({ primaryKey: "pKey", attrs: { height: "ThePersonSelfHeight" }, // ... });
同時也需要在model.js 文件進行相應的修改:
// people/model.js // ... height: DS.attr("number") // ...
即可在頁面中使用.height展示ThePersonSelfHeight 屬性的值。
Format Response在工作中,后端傳回來的數據往往會有些許嵌套或者是后端人員有自己的思考方式導致數據的結構和我們設想的有些許不同。這個時候我們可以通過 serialize() 以及 normalizeResponse() 這兩個方法來實現我們的需求。
比如后端傳給我們的數據有:
data: { type: "phone", id: 1, attributes: { brand: "Nokia", capacity: 64, size: { width: 70.9, height: 143.6, depth: 7.7, weight: 177 }, display: 5.8 } }
而我們在數據顯示中希望能直接展示的depth,而不想從size中取:
// phone/model.js import DS from "ember-data"; export default DS.Model.extend({ brand: DS.attr("string"), capacity: DS.attr("number"), depth: DS.attr("number"), display: DS.attr("number") });normalizeResponse()
我們可以通過 serializer.js 中的 normalizeResponse()方法來實現我們的需求:
// phone/serializer.js // ... normalizeResponse(store, primaryModelClass, payload, id, requestType) { payload.data.attributes.depth = payload.data.attributes.size.depth; delete payload.data.attributes.size; return this._super(...arguments); }
之后在 route.js 中我們請求數據:
// route.js // ... model() { return this.get("store").queryRecord("phone",{}) }
這樣頁面中我們就可以直接獲取 depth的值了:
{{model.brand}} {{model.capacity}} {{model.depth}} {{model.display}}
除了 normalizeResponse()方法,還有其他的幾個方法,如:
normalize()// phone/serializer.js // ... normalize(typeClass, hash) { hash.attributes.depth = hash.attributes.size.depth; delete hash.attributes.size; return this._super.apply(this, arguments); }
也可以起到相同的作用。這個方法可以在application中定義特定的 typeClass來針對調用。
normalizeQueryRecordResponse()在本文中我們獲取數據使用了 queryRecord(),所以我們還可以使用:
// phone/serializer.js // ... normalizeQueryRecordResponse(store, primaryModelClass, payload, id, requestType) { payload.data.attributes.depth = payload.data.attributes.size.depth; delete payload.data.attributes.size; return this._super(...arguments); },normalizeFindAllResponse()
相同的也可以聯想,當我們獲取數據為:
// route.js mode() { return this.get("store").findAll("phone"); }
這種情況的時候,可以使用:
// phone/serializer.js normalizeFindAllResponse(store, primaryModelClass, payload) { let data = payload.data.attributes; payload.data.attributes.depth = data.size ? data.size.depth : data.depth; delete payload.data.attributes.size; return this._super(...arguments); }
依然可以達到我們的目的。Emberjs 還提供其他的 normalize hook:
normalizeFindBelongsToResponse()
normalizeFindHasManyResponse()
normalizeFindManyResponse()
normalizeFindRecordResponse()
normalizeQueryResponse()
等其他修改創建的請求。
normalizeCreateRecordResponse()這個 hook 的使用需要從 創建一個 record 說起:
// arcicle/route.js or controller.js let articles = this.get("store").createRecord("article", { id: new Date().getTime(), title: "how to use serialize", body: "let try" });
在創建了 record 之后,可以在 EmberInspector 中的 Data 中查看到相應的 data。同時在 serializer.js中添加 normalizeCreateRecordResponse():
// article/serializer.js import DS from "ember-data"; export default DS.JSONAPISerializer.extend({ normalizeCreateRecordResponse(store, primaryModelClass, payload, id, requestType) { console.log(payload); return this._super(...arguments); } });
這時在瀏覽器看到這個 hook 并沒有執行。這個hook 執行的時機時在 保存 record 的時候:
// article/route.js or controller.js // ... articles.save()
刷新后即可看到 normalizeCreateRecordResponse() 此鉤子已經被執行。
同理,其他的更新/刪除相似:
normalizeDeleteRecordResponse
normalizeSaveResponse
normalizeUpdateRecordResponse
至此 DS.JSONAPISerialize 的相關屬性與method 已解釋完成。
Written By FrankWang.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105597.html
摘要:由于能力有限本示例不會完全自定義適配器和序列化器,示例仍然是使用官方推薦方式,重寫或者擴展以實現自定適配器和序列化器。在序列化器中調用響應請求的方法格式化返回的數據。上述就是的一個簡單實用示例。 文章來源:http://xcoding.tech/tags/Emberjs歡迎訪問源網站Ember Teach,Ember Teach致力于為您提供最權威、最前沿的Ember技術教程。。 ad...
摘要:話不多說,直接上干貨我們通過連接打開發現里面是真正拿到百度地圖的文件的地址是這個路徑于是我就在頁面上直接引入改成,事情就此解決 在emberjs框架中引入百度地圖,看網上有道友這么解決 道友文章我最近也恰好用到了這個,遇到了模板中引入引入百度地圖時拿不到BMap對象的尷尬事。 話不多說,直接上干貨 我們通過連接打開http://api.map.baidu.com/api?v=2.0發現...
摘要:話不多說,直接上干貨我們通過連接打開發現里面是真正拿到百度地圖的文件的地址是這個路徑于是我就在頁面上直接引入改成,事情就此解決 在emberjs框架中引入百度地圖,看網上有道友這么解決 道友文章我最近也恰好用到了這個,遇到了模板中引入引入百度地圖時拿不到BMap對象的尷尬事。 話不多說,直接上干貨 我們通過連接打開http://api.map.baidu.com/api?v=2.0發現...
摘要:話不多說,直接上干貨我們通過連接打開發現里面是真正拿到百度地圖的文件的地址是這個路徑于是我就在頁面上直接引入改成,事情就此解決 在emberjs框架中引入百度地圖,看網上有道友這么解決 道友文章我最近也恰好用到了這個,遇到了模板中引入引入百度地圖時拿不到BMap對象的尷尬事。 話不多說,直接上干貨 我們通過連接打開http://api.map.baidu.com/api?v=2.0發現...
摘要:在文件夾內創建,內容如下創建,內容如下使用安裝依賴在的頭部加入調用命令,同時在你的默認瀏覽器中打開。最后,我們更新下,給每個報道添加鏈接修改完畢地后,可以在瀏覽器中直接看到結果。 編者注:我們發現了有趣的系列文章《30天學習30種新技術》,正在翻譯,一天一篇更新,年終禮包。下面是第19天的內容。 到目前為止,我們這一系列文章涉及了Bower、AngularJS、GruntJS、P...
閱讀 1860·2021-11-15 11:39
閱讀 1226·2021-10-18 13:29
閱讀 1187·2021-08-31 09:42
閱讀 2740·2019-08-30 11:11
閱讀 2116·2019-08-26 12:12
閱讀 2115·2019-08-26 10:17
閱讀 3391·2019-08-23 18:38
閱讀 3228·2019-08-23 18:38