2015-04-16 2 views
1

Я создаю компонент, который отображает серию общих полей ввода. Магазин поддержка использует простой массив пар ключ-значение для управления данными:Как получить ссылку на целевой элемент внутри обратного вызова

[ 
{fieldkey: 'Signs and Symptoms', value:'fever, rash'}, 
{fieldkey: 'NotFeelingWell', value:'false'}, 
{fieldkey: 'ReAdmission', value:'true'}, 
{fieldkey: 'DateOfEvent', value:'12/31/1999'} 
] 

Для того, чтобы устранить много шаблонного кода, связанные с данными связывания компонент использует те же клавиши при генерации HTML-разметку (см. атрибут 'data-fieldname').

var Fields = React.createClass({ 

handleOnChange:function(e){ 

    Actions.updateField({key:e.target.attributes['data-fieldname'].value, value:e.target.value}) 
}, 
setValue:function(){ 
    var ref = //get a reference to the DOM element that triggered this call 
    ref.value = this.props.form.fields[ref.attributes['data-fieldname']] 
}, 

render:function(){ 


return (<div className="row"> 
    <Input data-fieldname="Signs and Symptoms" type="text" label='Notes' defaultValue="Enter text" onChange={this.handleOnChange} value={this.setValue()} /> 
    <Input data-fieldname="NotFeelingWell" type="checkbox" label="Not Feeling Well" onChange={this.handleOnChange} value={this.setValue()} /> 
    <Input data-fieldname="ReAdmission" type="checkbox" label="Not Feeling Great" onChange={this.handleOnChange} value={this.setValue()} /> 
    <Input data-fieldname="DateOfEvent" type="text" label="Date Of Event" onChange={this.handleOnChange} value={this.setValue()} /> 

</div>) 
} 

})

Моя цель состоит в том, чтобы использовать одни и те же две функции для записи/чтения из магазина для всех входов и без дублирования кода (т.е. я не хочу, чтобы добавить REFS декларацию к каждому ввод, который дублирует ключ, уже сохраненный в 'data-fieldname'). Все работает плавно при обратном вызове, связанном с событием onChange. Однако я не уверен, как получить ссылку на рассматриваемый узел DOM в функции setValue.

Заранее спасибо

+0

На данный момент 'this.setValue()' выполняется,/элемент компонент, который связан с этим вызовом делает даже еще не существует. –

+0

Точка хорошо приняты. Можете ли вы предложить альтернативный подход, который позволяет избежать дублирования ключей? –

+1

Хранить информацию в виде массива объектов (например) и генерировать элементы динамически? –

ответ

1

Я не уверен, если я понимаю ваш вопрос правильно, но уменьшить шаблонного я бы сопоставить массив для создания полей ввода:

render:function(){ 
var inputs = []; 
this.props.form.fields.map(function(elem){ 
    inputs.push(<Input data-fieldname={elem.fieldkey} type="text" label="Date Of Event" onChange={this.handleOnChange} value={elem.value} />); 
}); 

return (<div className="row"> 
    {inputs} 

</div>) 
} 

Это всегда будет отображать данные в реквизитах. Поэтому, когда handleOnChange запускается, компонент будет переписываться с новым значением. На мой взгляд, этот способ лучше, чем прямой доступ к узлу DOM.

+0

Отлично, и спасибо! Такое простое и очевидное решение, смущенный, я этого не видел. –

0

Если вы хотите использовать динамическую информацию на входе, вам необходимо передать ее через массив и создать цикл.

Вот небольшой пример, основанный на коде Dustin:

var fieldArray = [ //replace by this.props.form.fields 
    { 
     fieldkey: 'Signs and Symptoms', 
     value: 'fever, rash', 
     type: 'text', 
     label: 'Notes' 
    }, 
    { 
     fieldkey: 'NotFeelingWell', 
     value: 'false', 
     type: 'checkbox', 
     label: 'Not Feeling Well' 
    }, 
]; 

var Fields = React.createClass({ 

    handleOnChange:function(e){ 
     var fieldKey = e.target.attributes['data-fieldname'].value; 

     Actions.updateField({ 
      key: fieldKey, 
      value: e.target.value 
     }) 
    }, 

    render() { 
     var inputs = []; 

     fieldArray.map(function(field) { //replace by this.props.form.fields 
      inputs.push(
       <Input 
       data-fieldname={field.fieldkey} 
       value={field.value} 
       type={field.type} 
       label={field.label} 
       onChange={this.handleOnChange} /> 
      ); 
     }.bind(this)); 

     return (
      <div className="row"> 
       {inputs} 
      </div> 
     ); 
    } 

}); 
+0

Награжден Дастин ответом, поскольку он был первым, но я поддержал вас. –

+0

haha ​​ok, thanks :) –

Смежные вопросы