2016-07-27 64 views
3

ramda如何一次更新多個屬性?我能得到的最接近的是使用R.evolve()evolve希望我使用轉換函數修改屬性。我想直接做。但是,R.assoc()允許我一次只修改一個屬性,並且必須使用字符串指定屬性。更新多個屬性

這是我要做的事現在evolve

const STATE_INITIAL = { 
    isDisabled: true, 
    isLoading: false 
}; 

R.evolve({ 
    isDisabled: R.not, 
    isLoading:() => true // I don't want to set a value using a function 
    }, state) 

在JS我會在object-spread運營商,我會得到一個新的對象:

{ ...state, isDisabled: !state.isDisabled, isLoading: true} 

回答

1

一種選擇是使用鏡頭:

const isDisabled = R.lensProp('isDisabled'); 
const isLoading = R.lensProp('isLoading'); 

// toggle :: State -> State 
const toggle = R.pipe(
    R.over(isDisabled, R.not), 
    R.set(isLoading, true) 
); 

toggle({isDisabled: true, isLoading: false}); 
// => {isDisabled: false, isLoading: true} 

請參閱R.lensProp,R.overR.set

+0

有趣的選項,大衛。感謝您的分享。雖然很詳細。我現在讓答案不被接受。也許有人會用另一種解決方案。如果沒有新的出現,我會接受答案。 – zatziky

1

Ramda試圖讓事情變得簡單,所以容易有沒有一個很好的技術,將允許您使用功能一個屬性和其它的值,除了通過管道它們作爲大衛錢伯斯暗示。他的版本,這也可以寫成這樣:

const toggle = R.pipe(
    R.over(R.lensProp('isDisabled'), R.not), 
    R.set(R.lensProp('isLoading'), true) 
) 

肯定比

const toggle = state => { 
    ...state, 
    isDisabled: !state.isDisabled, 
    isLoading: true  
} 

有點冗長,但它似乎並沒有那麼糟糕。但是,如果你反對使用功能,這兩個屬性是不是太強,有你的原始版本evolve一個變體是相當簡單:

const toggle = R.evolve({ 
    isDisabled: R.not, 
    isLoading: R.T 
}) 

R.T僅僅是速記R.always(true)

+0

斯科特,謝謝你的意見。當R.T和R.F支持時,'R.evolve'對我來說似乎相當不錯。 – zatziky