欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript利用normalizr實現(xiàn)復(fù)雜數(shù)據(jù)轉(zhuǎn)換

 更新時間:2022年07月25日 15:17:07   作者:jump__jump  
當我們需要進行數(shù)據(jù)轉(zhuǎn)換以便拆分和維護時,可以使用redux作者 Dan Abramov 編寫的normalizr來處理數(shù)據(jù),本文將為大家詳細講講其用法,感興趣的可以了解一下

筆者曾經(jīng)開發(fā)過一個數(shù)據(jù)分享類的小程序,分享邏輯上類似于百度網(wǎng)盤。當前數(shù)據(jù)可以由被分享者加工然后繼續(xù)分享(可以控制數(shù)據(jù)的過期時間、是否可以加工數(shù)據(jù)以及繼續(xù)分享)。

分享的數(shù)據(jù)是一個深度嵌套的 json 對象。在用戶讀取分享數(shù)據(jù)時存入小程序云數(shù)據(jù)庫中(分享的數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)有差異,沒使用業(yè)務(wù)服務(wù)器進行維護)。如果拿到數(shù)據(jù)就直接存儲的話,很快云數(shù)據(jù)庫就會變得很大,其次我們也沒辦法分析各項和檢索各項子數(shù)據(jù)給予分享者。

這時候需要進行數(shù)據(jù)轉(zhuǎn)換以便拆分和維護。我們可以使用 redux 作者 Dan Abramov 編寫的 normalizr 來處理數(shù)據(jù)。

normalizr 創(chuàng)立的初衷是處理深層,復(fù)雜的嵌套的對象。

如何使用

稍微修改一下官方的例子,假定獲取到如下書籍的數(shù)據(jù):

{
  id: "1",
  title: "JavaScript 從入門到放棄",
  // 作者
  author: {
    id: "1",
    name: "chc"
  },
  // 評論
  comments: [
    {
      id: "1",
      content: "作者寫的太好了",
      commenter: {
        id: "1",
        name: "chc"
      }
    },
     {
      id: "2",
      content: "樓上造假數(shù)據(jù)哈",
      commenter: {
        id: "2",
        name: "dcd"
      }
    },
  ]
}

這時候我們可以寫出 3 個主體: 書籍信息、評論以及用戶。我們先從基礎(chǔ)的數(shù)據(jù)來構(gòu)造模式:

import { normalize, schema } from 'normalizr';

// 構(gòu)造第一個實體 用戶信息
const user = new schema.Entity('users');

// 構(gòu)造第二個實體 評論
const comment = new schema.Entity('comments', {
  // 評價者是用戶
  commenter: user
});

// 構(gòu)造第三個實體 書籍
const book = new schema.Entity('books', {
  // 作者
  author: user,
  // 評論
  comments: [comment]
});

// 傳入數(shù)據(jù)以及當前最大的 schema 信息
const normalizedData = normalize(originalData, book);

先來看一下最終數(shù)據(jù)。

{
  "entities": {
    "users": {
      "1": {
        "id": "1",
        "name": "chc"
      },
      "2": {
        "id": "2",
        "name": "dcd"
      }
    },
    "comments": {
      "1": {
        "id": "1",
        "content": "作者寫的太好了",
        "commenter": "1"
      },
      "2": {
        "id": "2",
        "content": "樓上造假數(shù)據(jù)哈",
        "commenter": "2"
      }
    },
    "books": {
      "1": {
        "id": "1",
        "title": "JavaScript 從入門到放棄",
        "author": "1",
        "comments": [
          "1",
          "2"
        ]
      }
    }
  },
  "result": "1"
}

去除其他信息,我們可以看到獲取了 3 個不同的實體對象, users,comments,books。對象的鍵為當前 id,值為當前平鋪的數(shù)據(jù)結(jié)構(gòu)。這時候我們就可以使用對象或者數(shù)組(Object.values) 來新增和更新數(shù)據(jù)。

解析邏輯

看到這里,大家可能是很懵的。先不管代碼實現(xiàn),這里先分析一下庫是如何解析我們編寫的 schema 的,以便大家可以在實際場景中使用,再看一遍數(shù)據(jù)和 schema 定義:

數(shù)據(jù)結(jié)構(gòu)

{
  id: "1",
  title: "JavaScript 從入門到放棄",
  // 作者
  author: {
    id: "1",
    name: "chc"
  },
  // 評論
  comments: [
    {
      id: "1",
      content: "作者寫的太好了",
      commenter: {
        id: "1",
        name: "chc"
      }
    },
     {
      id: "2",
      content: "樓上造假數(shù)據(jù)哈",
      commenter: {
        id: "2",
        name: "dcd"
      }
    },
  ]
}

書籍信息是第一層對象,數(shù)據(jù)中有 id, title, author, comments,對應(yīng) schema 如下

const book = new schema.Entity('books', {
  // 作者
  author: user,
  // 一本書對應(yīng)多個評論,所以這里使用數(shù)組
  comments: [comment]
});

其中 id ,title 是 book 本身的屬性,無需關(guān)注,把需要解析的數(shù)據(jù)結(jié)構(gòu)寫出來。books 字符串與解析無關(guān),對應(yīng) entities 對象的 key。

再看 user

const user = new schema.Entity('users');

user 沒有需要解析的信息,直接定義實體即可。

最后是評論信息

const comment = new schema.Entity('comments', {
  // 評價者是用戶
  commenter: user
});

{
  id: "1",
  content: "作者寫的太好了",
  commenter: {
    id: "1",
    name: "chc"
  }
}

把 comments 從原本的數(shù)據(jù)結(jié)構(gòu)中拿出來,實際也就很清晰了。

高階用法

處理數(shù)組

normalizr 可以解析單個對象,那么如果當前業(yè)務(wù)傳遞數(shù)組呢?類似于 comment 直接這樣使用即可:

[
  {
    id: '1',
    title: "JavaScript 從入門到放棄"
    // ...
  },
  {
    id: '2',
    // ...
  }
]

const normalizedData = normalize(originalData, [book]);

反向解析

我們只需要拿到剛才的 normalizedData 中的 result 以及 entities 就可以獲取之前的信息了。

import { denormalize, schema } from 'normalizr';

//...

denormalize(normalizedData.result, book, normalizedData.entities);

Entity 配置

開發(fā)中可以根據(jù)配置信息重新解析實體數(shù)據(jù)。

const book = new schema.Entity('books', {
  // 作者
  author: user,
  // 一本書對應(yīng)多個評論,所以這里使用數(shù)組
  comments: [comment]
}, {
  // 默認主鍵為 id,否則使用 idAttribute 中的數(shù)據(jù),如 cid,key 等
  idAttribute: 'id',
  // 預(yù)處理策略, 參數(shù)分別為 實體的輸入值, 父對象
  processStrategy: (value, parent, key) => value,
  // 遇到兩個id 相同數(shù)據(jù)的合并策略,默認如下所示,我們還可以繼續(xù)修改
  mergeStrategy: (prev, prev) => ({
    ...prev,
    ...next,
    // 是否合并過,如果遇到相同的,就會添加該屬性
    isMerge: true
  }),
});

// 看一下比較復(fù)雜的例子,以 user 為例子
const user = new schema.Entity('users', {
}, {
  processStrategy: (value, parent, key) => {
    // 增加父對象的屬性
    // 例如 commenter: "1" => commenterId: "1" 或者 author: "2" => "authorId": "2"
    // 但是目前還無法通過 delete 刪除 commenter 或者 author 屬性
    parent[`${key}Id`] = value.id

    // 如果是從評論中獲取的用戶信息就增加 commentIds 屬性
    if (key === 'commenter') { 
      return {
        ...value, 
        commentIds: [parent.id] 
      } 
    }
    // 不要忘記返回 value, 否則不會生成 user 數(shù)據(jù)
    return {
      ...value,
      bookIds: [parent.id]
    };
  }
  mergeStrategy: (prev, prev) => ({
    ...prev,
    ...next,
    // 該用戶所有的評論歸并到一起去
    commentIds: [...prev.commentIds, ...next.commentIds],
    // 該用戶所有的書本歸并到一起去
    bookIds: [...prev.bookIds, ...next.bookIds],
    isMerge: true
  }),
})

// 最終獲取的用戶信息為
{
  "1": {
    "id": "1",
    "name": "chc"
    // 用戶 chc 寫了評論和書籍,但是沒有進行過合并
    "commentIds": ["1"],
    "bookIds": ["1"],
  },
  "2": {
    "id": "2",
    "name": "dcd",
    // 用戶 dcd 寫了 2 個評論,同時進行了合并處理
    "commentIds": [
      "2",
      "3"
    ],
    "isMerge": true
  }
}

當然了,該庫也可以進行更加復(fù)雜的數(shù)據(jù)格式化,大家可以通過 api 文檔 來進一步學(xué)習(xí)和使用。

其他

當然了,normalizr 使用場景畢竟有限,開源負責(zé)人也早已換人。目前主庫已經(jīng)無人維護了(issue 也也已經(jīng)關(guān)閉)。當然了,normalizr 代碼本身也是足夠穩(wěn)定。

筆者也在考慮一些新的場景使用并嘗試為 normalizr 添加一些新的功能(如 id 轉(zhuǎn)換)和優(yōu)化(ts 重構(gòu)),如果您在使用 normalizr 的過程中遇到什么問題,也可以聯(lián)系我,存儲庫目前在 normalizr-helper 中。

到此這篇關(guān)于JavaScript利用normalizr實現(xiàn)復(fù)雜數(shù)據(jù)轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)JavaScript normalizr復(fù)雜數(shù)據(jù)轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • discuz中用到的javascript函數(shù)解析

    discuz中用到的javascript函數(shù)解析

    discuz中用到的js不論是多瀏覽器兼容性和實用性都是非常不錯的,推薦大家看下
    2008-05-05
  • 詳解webpack4多入口、多頁面項目構(gòu)建案例

    詳解webpack4多入口、多頁面項目構(gòu)建案例

    這篇文章主要介紹了詳解webpack4多入口、多頁面項目構(gòu)建案例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • js操作二級聯(lián)動實現(xiàn)代碼

    js操作二級聯(lián)動實現(xiàn)代碼

    網(wǎng)上二級(多級)聯(lián)動的例子也不少,有各種不同的操作方法。我所采用的方法網(wǎng)上也應(yīng)該有的,不過我還沒有看到過。
    2010-07-07
  • JS數(shù)組去重的6種方法完整實例

    JS數(shù)組去重的6種方法完整實例

    這篇文章主要介紹了JS數(shù)組去重的6種方法,結(jié)合完整實例形式總結(jié)分析了javascript針對數(shù)組去除重復(fù)項的相關(guān)原理與操作技巧,需要的朋友可以參考下
    2018-12-12
  • JavaScript?split()方法定義及更多實例

    JavaScript?split()方法定義及更多實例

    這篇文章主要給大家介紹了關(guān)于JavaScript?split()方法定義及更多實例的相關(guān)資料,js里的split()方法大家都知道用于將字符串轉(zhuǎn)化為字符串數(shù)組,文中通過代碼實例介紹的非常詳細,需要的朋友可以參考下
    2024-03-03
  • javascript實現(xiàn)粘貼qq截圖功能(clipboardData)

    javascript實現(xiàn)粘貼qq截圖功能(clipboardData)

    這篇文章主要介紹了javascript實現(xiàn)粘貼qq截圖功能,利用clipboardData在網(wǎng)頁中實現(xiàn)截屏粘貼的功能,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 優(yōu)雅而高效的JavaScript?try...catch語句詳解(js異常處理)

    優(yōu)雅而高效的JavaScript?try...catch語句詳解(js異常處理)

    這篇文章主要給大家介紹了關(guān)于JavaScript中try...catch語句的相關(guān)資料,也就是js異常處理方法,try...catch是JavaScript中的錯誤處理機制,它的作用是捕獲和處理可能發(fā)生的錯誤,以避免程序崩潰,需要的朋友可以參考下
    2024-01-01
  • 解決webpack多頁面內(nèi)存溢出的方法示例

    解決webpack多頁面內(nèi)存溢出的方法示例

    這篇文章主要介紹了解決webpack多頁面內(nèi)存溢出的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Bootstrap每天必學(xué)之按鈕(一)

    Bootstrap每天必學(xué)之按鈕(一)

    Bootstrap每天必學(xué)之按鈕,本文講解的就是大家最為常用的button按鈕的樣式,感興趣的小伙伴們可以參考一下
    2015-11-11

最新評論