2015-12-24 27 views
0

當用戶單擊正方形時,它將變爲currentHtmlObject。我希望人們能夠在右側邊欄中更新它的屬性。當用戶更改表單中的輸入時更新所選對象

我不知道如何採取一個單一的輸入字段,並更新一個對象的屬性,我在一個react-redux狀態下持有並更新主查看區域DrawingCanvas

我有點接近,我輸入表單的信息是激活我的減速器和動作。但我無法弄清楚如何區分lefttop

// React 
import React from 'react' 

export class RightSidebar extends React.Component { 
    constructor(props) { 
     super(props) 
    } 

    handleChange(evt) { 
     console.log(evt) 
     this.props.onUpdateCurrentHtmlObject(evt.target.value) 
    } 

    render() { 
     const { currentHtmlObject } = this.props 

     return (
      <form> 
       {this.props.currentHtmlObject.id} 
       <div className="right-sidebar"> 
        <div className="form-group"> 
         <label>Position X</label> 
         <input 
          type="number" 
          name="left" 
          className="form-control" 
          value={this.props.currentHtmlObject.styles ? this.props.currentHtmlObject.styles.left : ''} 
          onChange={this.handleChange.bind(this)} /> 
        </div> 

        <div className="form-group"> 
         <label>Position Y</label> 
         <input 
          type="number" 
          className="form-control" 
          value={this.props.currentHtmlObject.styles ? this.props.currentHtmlObject.styles.top : ''} 
          onChange={this.handleChange.bind(this)} /> 
        </div> 
       </div> 
      </form> 
     ) 
    } 
} 

RightSidebar.defaultProps = { 
    currentHtmlObject: { 
     styles: { 
      left: null, 
      top: null 
     } 
    } 
} 

enter image description here

+0

會不只是傳遞更多的數據到'onUpdateCurrentHtmlObject'回調?就像元素名稱一樣? – acjay

回答

2

無需左側和頂部之間的區別,讓我們假設你有一個名爲動作的更新和所有它是更新所選對象的屬性。下面是操作方法可能是什麼樣子:

updateSelectedObj(id, payload){ 
    return { 
     type: UPDATE_SELECTED_OBJ, 
     id: id, 
     payload: payload 
    } 
} 

這是你的事件處理程序可能看起來像在class RightSidebar

handleChange(evt) { 
    // since your top and left input fields have a corresponding name property, evt.target.name will return either `left` or `top` 
    store.dispatch(updateSelectedObj({styles:{evt.target.name:evt.target.value}}) 
} 

這裏是你的減速機:

[UPDATE_SELECTED_OBJ]: (state, action) => { 
    // I assume you have a list of objects in the canvas but only one can 
    // be selected at a time. and I assume the name of the list is objList 
    let selectedObj = state.objList.filter(obj => obj.id == action.id)[0] 
    selectedObj = Object.assign({}, selectedObj, action.payload) 
    return { objList: state.objList.map(obj => obj.id === action.id? Object.assign({}, obj, selectedObj : obj) } 
} 
1

我可能建議簡化組件本身。對不起,簡單:)。當我有一些時間時,我可以更新更多的上下文。

這是一個精簡的例子,但基本上把每個「數字輸入」看作只需要valueonChange(發出值,而不是事件)。

您將使用react-redux's connect,因此updateObject是一個回調函數,接受將要合併到currentObject狀態中的「補丁數據」。

/** 
* @param currentObject 
* @param updateObject An already bound action creator that accepts payload to "update object" 
*/ 
function SideBar({currentObject, updateObject}) { 
    const {styles} = currentObject; 
    return (
    <div> 
     <NumberInput 
     value={styles.left} 
     onChange={left => updateObject({left})} 
     /> 
     <NumberInput 
     value={styles.top} 
     onChange={top => updateObject({top})} 
     /> 
    </div> 
) 
} 

connect語句可能看起來像

const SideBarContainer = connect(
    (state, {objectId}) => ({ 
    currentObject: _.find(state.objects, {id}), 
    }), 
    (dispatch, {objectId}) => ({ 
    updateObject: data => dispatch(
     actions.updateObject(objectId, data) 
    ) 
    }) 
)(SideBar); 

與實際使用情況,可能像

<SidebarContainer objectId={currentObjectId} /> 
相關問題