在反应

时间:2015-12-16 20:07:34

标签: javascript meteor reactjs

我有一系列电子邮件(作为更大型号的一部分)。这些显示在单独的行中,每个行都有删除按钮(地址本身可以直接在输入框中更新)。不幸的是,当使用map函数渲染输入时,我不知道如何做出反应。 (我正在将流星火焰项目转换为流星反应)。

所有内容都呈现,但如何附加更改事件以便我可以更新我的电子邮件数组? onChange +值需要以某种方式设置。

这是地图功能

return this.data.emailGroup.emails.map((email) => {
            return (
                <div key={email} className="input-group">
                    <input type="text" className="form-control" onChange={self.handleEmailListChange} value={email}/>

                    <div className="input-group-btn">
                        <button type="button"
                                className="btn btn-default remove-email"><span
                            className="glyphicon glyphicon-remove"></span></button>
                    </div>
                </div>
            );
        });

初始状态(使用db:

中的数据填充
 getInitialState() {
      return {
          name : '',
          description: '',
          emails : [],
          newEmailAddress : ''
      }
    },

根据请求,这里是render方法(它需要一个getContent方法。getcontent方法就在那里,因为在meteor中我需要等待数据,所以在此期间我需要一个加载状态。

   getContent() {
        return (

            <div className="box box-success">
                <div className="box-header with-border">
                    <h3 className="box-title">List of emails</h3>
                </div>
                <form role="form" className="form-horizontal">
                    <div className="box-body">
                        <p>Below is a list of email addresses which are added to this email group. If
                            you
                            want
                            to add more
                            you can add them one by one by inputting in the box below or add a list into
                            the
                            same box (email
                            addresses have to be seperated by either a space or ;) then press Add to add
                            to
                            the
                            list. You can edit
                            the addresses directly as well as remove them.</p>
                        <div className="input-group">
                            <input type="text" className="form-control"

                                   value={this.state.newEmailAddress}
                                   onChange={this.handleAddNewEmail}
                                   placeholder="Email addresses seperated by a space or a semicolon ; i.e. test1@test.se;test2@test.se"/>
                    <span className="input-group-btn">
                      <button type="button" onClick={this.handleAddNewEmailButton} className="btn btn-info btn-flat add-email">Add</button>
                    </span>
                        </div>
                        <br/>
                        {this.renderEmail()}
                    </div>
                </form>
            </div>
        )
    },
    render()
    {
    var contentStyle = {
        minHeight : '946px'
    };
        return (
            <div className="content-wrapper" style={contentStyle}>
                <section className="content-header">
                    <h1>
                        {this.data.emailGroup? this.data.emailGroup.name : 'hello'}
                    </h1>
                    <small> Created by: Christian Klinton</small>
                    <br/>
                    <small> Last updated by: Christian Klinton - 2015-11-12 08:10:11</small>
                    <ol className="breadcrumb">
                        <li><a href="/emailGroups"><i className="fa fa-dashboard"></i> Home</a></li>
                        <li><a href="/emailGroups">Email groups</a></li>
                        <li className="active">{this.data.emailGroup? this.data.emailGroup.name : 'loading'}</li>
                    </ol>
                </section>
                <section className="content">
                    <div className="row">
                        <div className="col-md-6">
                            <div className="box box-primary">
                                <div className="box-header with-border">
                                    <h3 className="box-title">Information</h3>

                                </div>
                                <form role="form">
                                    <div className="box-body">
                                        <div className="form-group">
                                            <label htmlFor="inputName">Name</label>
                                            <input type="email" className="form-control" id="name"
                                                   onChange={this.handleNameChange}
                                                   placeholder="Set the name of the email group" autoComplete="off"
                                                  value={this.state.name}/>
                                        </div>

                                        <div className="form-group">
                                            <label>Description</label>
                                    <textarea className="form-control" rows="3" id="description"
                                              placeholder="Enter a description what and how the template is used..."
                                              onChange={this.handleDesriptionChange}
                                              value={this.state.description}
                                    ></textarea>
                                        </div>


                                    </div>
                                </form>
                            </div>
                        </div>
                        <div className="col-md-6">
                            {this.data.emailGroup? this.getContent() : <p>Loading</p> }
                        </div>
                        <div className="form-group">
                            <div className="col-sm-offset-8 col-sm-4">
                                <div className="pull-right">
                                    <button className="btn btn-primary">Delete all</button>
                                    <button className="btn btn-primary save">Save</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </section>
            </div>
        )
    }

3 个答案:

答案 0 :(得分:10)

React要求你为渲染数组中的每个元素赋予一些独特的东西,它被称为key,它是一个属性。

如果您不知道要为键分配什么,只需为其分配数组的索引:

this.props.doors.map((door, index) => (
    <div key={index} className="door"></div>
));

以下是适用于您的问题的相同解决方案:

return this.data.emailGroup.emails.map((email, index) => {
    return (
        <div key={index} className="input-group">
            <input type="text"
                   className="form-control"
                   onChange={self.handleEmailListChange.bind(this, index)} value={email}/>
        </div>
    );
});

请注意我如何绑定handleEmailListChange以接收修改后的电子邮件的索引。如果handleEmailListChange接受索引,则可以在州内更新修改后的电子邮件:

handleEmailListChange: function(index, event) {
    var emails = this.state.emails.slice(); // Make a copy of the emails first.
    emails[index] = event.target.value; // Update it with the modified email.
    this.setState({emails: emails}); // Update the state.
}

答案 1 :(得分:2)

您应该将Array.map直接放在render()功能中。请注意每个数组元素都包含在父元素(<div>此处)内,并且必须具有唯一的key={}

class ArrayMap extends React.Component{
  //your functions
  handleEmailChanged(key){
    // Handle email
  }
  render(){
    return(
      <div>
        {
          this.data.emailGroup.emails.map((email) => {
            <div key={email.key}>
              <button onClick={this.handleEmailChanged.bind(this,email.key)}/>
            </div>
          });
        }
      </div>
    );
  }
}

答案 2 :(得分:1)

我相信你所寻找的是这样的:

MyPage = React.createClass({
  mixins: [ReactMeteorData],

  getMeteorData() {
    // ...
  },

  render() {
    const emails = this.data.emailGroup.emails.map((email) => {
      return (
        <div key={email} className="input-group">
          <input type="text" className="form-control"
                 onChange={this.handleEmailListChange} value={email} />

          <div className="input-group-btn">
            <button type="button"
                    className="btn btn-default remove-email"><span
              className="glyphicon glyphicon-remove" /></button>
          </div>
        </div>
      );
    });

    return <div>
      {emails}
    </div>
  }
});

我将self更改为this。由于您使用的是ES6箭头功能,因此无需指定self = this