簡體   English   中英

在Immutable.js中解析嵌套記錄

[英]Parsing nested Records in Immutable.js

假設我使用Immutable.js定義了以下記錄:

var Address = Immutable.Record({street: '', city: '', zip: ''});
var User = Immutable.Record({name: '', address: new Address()});

如何將普通的javascript對象轉換為用戶記錄? 我嘗試了以下但它不會產生預期的輸出:

var user = new User({name: 'Foo', address: {street: 'Bar', city: 'Baz'}});
// => Record { "name": "Foo", "address": [object Object] }

我知道可以顯式創建地址記錄:

var user = new User({name: 'Foo', address: new Address({street: 'Bar', city: 'Baz'})});
// => Record { "name": "Foo", "address": Record { "street": "Bar", "city": "Baz", "zip": "" } }

但這不是我想要的解決方案。 想象一下,你有記錄嵌套了幾個級別,並希望將數據存儲/檢索為JSON(例如在數據庫中)。 我想使用實際的用戶記錄結構作為重新創建嵌套記錄的模式信息。 或者有更好的方法來表示嵌套和結構化的不可變數據嗎?

Record結構的預期用途不是驗證提供的數據的結構,只是為了確定允許的密鑰集,如果沒有給出,則提供默認值。

因此,使用您的示例,如果您在不提供地址的情況下初始化記錄,您將獲得適用於Address的Immutable.Record對象:

var user = new User({name: 'Foo'});
// => Record { "name": "Foo", "address": Record { "street": "", "city": "", "zip": "" } }

實現你想要的一種hackish方法是使用自定義reviver函數在Immutable.fromJS方法上編寫一個包裝器:

Immutable.Record.constructor.prototype.fromJS = function(values) {
  var that = this;
  var nested = Immutable.fromJS(values, function(key, value){
    if(that.prototype[key] && that.prototype[key].constructor.prototype instanceof Immutable.Record){return that.prototype[key].constructor.fromJS(value)}
    else { return value }
  });
  return this(nested);
}

然后你可以像這樣使用它:

var user = User.fromJS({name: 'Foo', address: {street: 'Bar', city: 'Baz'}});

// => User { "name": "Foo", "address": Record { "street": "Bar", "city": "Baz", "zip": "" } }

但是,如果您想要正確檢查數據結構,我建議將Immutable.js與一些靜態類型檢查器一起使用,例如http://flowtype.org/http://www.typescriptlang.org/

您可以在構造函數中將User子類化為Record定義和解析address

import {Record} from 'immutable'

const Address = Record({street: '', city: '', zip: ''});
class User extends Record({name: '', address: new Address()}) {
  constructor({name, address} = {}) {
    super({name, address: new Address(address)})
  }
}

const user = new User({
  name: 'Andy',
  address: {
    street: 'wherever',
    city: 'Austin',
    zip: 'TX'
  }
})

console.log(user)
console.log('user.address instanceof Address:', user.address instanceof Address)

const user2 = new User({name: 'Bob'})

console.log(user2)
console.log('user2.address instanceof Address:', user2.address instanceof Address)

輸出:

User { "name": "Andy", "address": Record { "street": "wherever", "city": "Austin", "zip": "TX" } }
user.address instanceof Address: true
User { "name": "Bob", "address": Record { "street": "", "city": "", "zip": "" } }
user2.address instanceof Address: true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM