使用React等效的Angular 1.X ng-options

时间:2017-02-22 00:13:55

标签: angularjs reactjs equivalent

Angular 1.X对于选择下拉列表中的选项有 ng-options ,每个项目都是对象。在纯HTML中,选项的值只能是字符串。当您在Angular中选择一个选项时,您可以看到实际选中的对象,而在纯HTML中,您只能获得该字符串值。

  

你如何在React(+ Redux)中完成相同的工作?

2 个答案:

答案 0 :(得分:0)

我提出了一个解决方案,它不使用JSON.stringify / parse作为select React元素的值,也没有使用choice对象数组的索引作为值。

该示例是针对某个人的性别(男性或女性)的简单选择下拉菜单。每个选项都是具有id,text和value属性的实际对象。这是代码:

MySelect组件

import React, { Component } from 'react';

class MySelect extends Component {
  onGenderChange = (event) => {
    // Add the second argument -- the data -- and pass it along
    // to parent component's onChange function
    const data = { options: this.props.options };
    this.props.onGenderChange(event, data);
  }

  render() {
    const { options, selectedOption } = this.props;

    // Goes through the array of option objects and create an <option> element for each
    const selectOptions = options.map(
      option => <option key={option.id} value={option.value}>{option.text}</option>
    );

    // Note that if the selectedOption is not given (i.e. is null),
    // we assign a default value being the first option provided
    return (
      <select
        value={(selectedOption && selectedOption.value) || options[0].value}
        onChange={this.onGenderChange}
      >
        {selectOptions}
      </select>
    );
  }
}

使用MySelect的应用程序组件

import _ from 'lodash';
import React, { Component } from 'react';

class App extends Component {
  state = {
    selected: null
  }

  onGenderChange = (event, data) => {
    // The value of the selected option
    console.log(event.target.value);
    // The object for the selected option
    const selectedOption = _.find(data.options, { value: parseInt(event.target.value, 10) });
    console.log(selectedOption);

    this.setState({
      selected: selectedOption
    });
  }

  render() {
    const options = [
      {
        id: 1,
        text: 'male',
        value: 123456
      },
      {
        id: 2,
        text: 'female',
        value: 654321
      }
    ];

    return (
      <div>
        <label>Select a Gender:</label>
        <MySelect
          options={options}
          selectedOption={this.state.selected}
          onGenderChange={this.onGenderChange}
        />
      </div>
    );
  }
}

Lodash用于在App组件的onGenderChange函数内的选择对象数组中查找选择对象。请注意,传递给MySelect组件的onChange需要两个参数 - 添加额外的数据参数以便能够访问选择对象(&#34; options&#34;)。有了它,您可以使用所选选项的选择对象设置状态(或调用动作创建者,如果使用Redux)。

答案 1 :(得分:0)

我在迁移 angular 1 应用程序以做出反应时遇到了同样的情况。而且我觉得这是一个我找不到的急需的功能,所以在这里我将 NgOption 的实现留在使用引导程序的反应中(您可以将其更改为您正在使用的任何内容),供任何缺少 goo'old angular 1 的人使用:

import React from 'react';
import { Form, InputGroup } from 'react-bootstrap';

interface props<T, U>{
  options: Array<T>,
  selected?: U,
  onSelect: (value: T) => any,
  as: (value: T) => string,
  trackBy: (value: T) => U,
  disabled?: boolean
}

type state = {}

export default class NgOptions extends React.Component<props<any, any>, state> {
  componentDidMount() {
    if (this.props.selected) {
      this.props.onSelect(this.props.options.find((o) => this.props.trackBy(o)===this.props.selected))
    }
  }
  
  public render() {
    return ( <InputGroup>
      <Form.Control as="select"
                    disabled={this.props.disabled}
                    onChange={(e) => this.props.onSelect(this.props.options.find((o) => this.props.trackBy(o)===e.target.value))}>
        {this.props.options.map( option =>
          <option key={this.props.trackBy(option)}
                  selected={this.props.selected===this.props.trackBy(option)}
                  value={this.props.trackBy(option)}>{this.props.as(option)}</option>
        )}
      </Form.Control>
    </InputGroup>
    )
  }
}