【问题标题】:Angular 1.X ng-options equivalent using ReactAngular 1.X ng-options 等效使用 React
【发布时间】:2017-02-22 00:13:55
【问题描述】:

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

在 React (+Redux) 中你是如何做到这一点的?

【问题讨论】:

  • 查看react-select。您还可以创建一个 selects 数组作为 option 元素的子元素。
  • @Andy_D 感谢您的建议。我实际上正在使用 Semantic UI React (react.semantic-ui.com/modules/dropdown),问题是每个选项的值只能是一个字符串。通过将对象字符串化为值,我找到了一种解决方法。我查看了 react-select 的源代码,他们这样做了。问题是我必须对我拥有的每个 onchange 函数进行 JSON 解析。我想知道是否有更好的方法。另一个想法是使用数组索引作为值并访问所有选项,然后使用索引缩小范围。

标签: angularjs reactjs equivalent


【解决方案1】:

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

这个例子是一个简单的选择一个人的性别的下拉菜单——无论是男性还是女性。这些选择中的每一个都是具有 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 需要两个参数——添加一个额外的数据参数以便能够访问选择对象(“选项”)。这样,您就可以使用所选选项的选择对象来设置状态(或者如果使用 Redux,则调用动作创建者)。

【讨论】:

    【解决方案2】:

    我在迁移 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>
        )
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 2014-02-19
      • 1970-01-01
      相关资源
      最近更新 更多