2016-07-27 59 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