2016-12-14 75 views
1

项目描述:我有一个像Google日历一样的日历,您可以在其中放置zoomIn和zoomOut按钮以及一个日期选择器,您可以在其中点击任何日期将日历移至该日期。如何在Redux/Atomic操作中同时更新两个不同缩减器中的两个值

商店的设计:我有一个过滤器减速机,我保持当前日历的范围(例如{开始:'01/01/2016',结束:'01/01/2017'}) ,也是一个UI减速,我保持当前的缩放级别(年的一个/月/周)

场景:当某人是个zoomLevel =“年”和点击上的日期选择日期,我需要去zoomLevel ='星期',并修改范围。

问题:如何使用zoomLevel和range同时更新商店?如果我不这样做,我的日历会由于不一致而中断,因为当我更新第一个值时,用户界面呈现所有内容。

UI减速机作为通用减速器的例子:

import * as actions from './action-types' 
import { omit } from 'lodash' 
import initialState from './initial-state' 
export * from './actions' 
export * from './selectors' 

// TODO: Eval. Tendria mas sentido hacer el switch por dominio? 
export default function ui(state = initialState, {type, meta: {domain = 'general'} = {}, payload: {key, value} = {}}) { 
    switch (type) { 
    case actions.SET: 
    return { 
     ...state, 
     [domain]: { 
     ...state[domain] || {}, 
     [key]: value 
     } 
    } 
    case actions.TOGGLE: 
    return { 
     ...state, 
     [domain]: { 
     ...state[domain] || {}, 
     [key]: !!!(state[domain] || {})[key] 
     } 
    } 
    case actions.TOGGLE_IN_ARRAY: 
    // No sirve para objetos 
    const index = state[domain] && state[domain][key] ? state[domain][key].indexOf(value) : -1 
    return index === -1 ? 
     { 
     ...state, 
     [domain]: { 
      ...state[domain] || {}, 
      [key]: [ 
      value, 
      ...state[domain][key] 
      ] 
     } 
     } : { 
     ...state, 
     [domain]: { 
      ...state[domain], 
      [key]: [ 
      ...state[domain][key].slice(0, index), 
      ...state[domain][key].slice(index + 1) 
      ] 
     } 
     } 
    case actions.DELETE: 
    return { 
     ...state, 
     [domain]: omit(state[domain], key) 
    } 
    case actions.CLEAR_DOMAIN: 
    return { 
     ...state, 
     [domain]: initialState[domain] 
    } 
    case actions.RESET_UI: 
    return { 
     ...initialState 
    } 
    default: 
    return state 
    } 
} 
+1

操作发送给所有的减速,这样你就可以处理两个减速器上的单一动作类型 –

+0

是的,谢谢达维。你是对的,那可能是一个解决方案。但我有一些UI模块的操作,比如updateUIElement和一些filter模块,比如updateFilter。这两个模块都是非常不可知的,我在项目之间重复使用它们,因此引入像updateCalendar这样的操作是我不喜欢的。可能没有办法,我最终会做出类似于你所说的话。 非常感谢 – kanedaki

+0

如果你不打算使用全局动作,并且你想同时发送几个动作,那么你可以使用https://github.com/tshelburne/redux-batched-actions –

回答

0

调度动作将被发送到根减速器减速都将依次向下传递给孩子减速器(取决于减速机实现)。

因此,如果你的根减速看起来是这样的:

export default combineReducers({ 
    filters, 
    ui, 
}); 

可以在每个减速器相同的动作回应是这样的:

function filters(state, action) { 
    case CLICK_ON_DATE: 
    return { 
     ...state, 
     start: ..., 
     end: ..., 
    }; 
    ... 
} 


function ui(state, action) { 
    case CLICK_ON_DATE: 
    return { 
     ...state, 
     zoomLevel: 'week', 
    }; 
    ... 
} 
+0

谢谢杨,你是完全正确的。问题在于我无法更改我的reducer,因为这些项目之间可以共享,并且他们不应该知道其他模块中的操作。 我已经添加了ui缩减器的代码,mayble它将阐明我的意思是通用的。 – kanedaki

相关问题