пользовательский редактор реагировать-сетки данных - PullRequest
0 голосов
/ 26 июня 2018

У меня странная проблема при попытке создать собственный редактор автозаполнения.

В основном я сделал то, что я извлек встроенный класс AutocompleteEditor, реорганизовал его в простой ES6 и переименовал класс в ProductSelectEditor. Никаких изменений в коде логики.

Когда я пытаюсь использовать его, я получаю сообщение об ошибке «Не удается прочитать свойство« onCommit »из неопределенного» при вызове handleChange ():

handleChange() {
  this.props.onCommit(); // props undefined
}

Теперь, если я заменю редактор реальным встроенным AutocompleteEditor, он будет работать просто отлично. Я не вижу какой-либо прямой причины, почему моя пользовательская версия не работает, когда только изменения, которые я делаю, - это рефакторинг кода без TypeScript, переименование класса и, в конечном итоге, экспорт класса по умолчанию? Любые подсказки о том, что я здесь не понимаю?

Ниже приведен весь переработанный код

import React from 'react'
import ReactDOM from 'react-dom'
import ReactAutocomplete from  'ron-react-autocomplete';
import PropTypes from 'prop-types';
import '../css/ron-react-autocomplete.css'
const { shapes: { ExcelColumn } } = require('react-data-grid')

let optionPropType = PropTypes.shape({
  id: PropTypes.required,
  title: PropTypes.string
});

export default class ProductSelectEditor extends React.Component {
  static propTypes = {
    onCommit: PropTypes.func,
    options: PropTypes.arrayOf(optionPropType),
    label: PropTypes.any,
    value: PropTypes.any,
    height: PropTypes.number,
    valueParams: PropTypes.arrayOf(PropTypes.string),
    column: PropTypes.shape(ExcelColumn),
    resultIdentifier: PropTypes.string,
    search: PropTypes.string,
    onKeyDown: PropTypes.func,
    onFocus: PropTypes.func,
    editorDisplayValue: PropTypes.func
  };

  static defaultProps = {
    resultIdentifier: 'id'
  };

  handleChange() {
    this.props.onCommit();
  }

  getValue() {
    let value;
    let updated = {};
    if (this.hasResults() && this.isFocusedOnSuggestion()) {
      value = this.getLabel(this.autoComplete.state.focusedValue);
      if (this.props.valueParams) {
        value = this.constuctValueFromParams(this.autoComplete.state.focusedValue, this.props.valueParams);
      }
    } else {
      value = this.autoComplete.state.searchTerm;
    }
    updated[this.props.column.key] = value;
    return updated;
  }

  getEditorDisplayValue() {
    let displayValue = {title: ''};
    let { column, value, editorDisplayValue } = this.props;
    if (editorDisplayValue && typeof editorDisplayValue === 'function') {
      displayValue.title = editorDisplayValue(column, value);
    } else {
      displayValue.title = value;
    }
    return displayValue;
  }

  getInputNode() {
    return ReactDOM.findDOMNode(this).getElementsByTagName('input')[0];
  }

  getLabel(item) {
    let label = this.props.label != null ? this.props.label : 'title';
    if (typeof label === 'function') {
      return label(item);
    } else if (typeof label === 'string') {
      return item[label];
    }
  }

  hasResults() {
    return this.autoComplete.state.results.length > 0;
  }

  isFocusedOnSuggestion() {
    let autoComplete = this.autoComplete;
    return autoComplete.state.focusedValue != null;
  }

  constuctValueFromParams(obj, props) {
    if (!props) {
      return '';
    }
    let ret = [];
    for (let i = 0, ii = props.length; i < ii; i++) {
      ret.push(obj[props[i]]);
    }
    return ret.join('|');
  }

  render() {
    let label = this.props.label != null ? this.props.label : 'title';
    return (<div height={this.props.height} onKeyDown={this.props.onKeyDown}>
      <ReactAutocomplete search={this.props.search} ref={(node) => this.autoComplete = node} label={label} onChange={this.handleChange} onFocus={this.props.onFocus} resultIdentifier={this.props.resultIdentifier} options={this.props.options} value={this.getEditorDisplayValue()} />
      </div>);
  }
}

1 Ответ

0 голосов
/ 26 июня 2018

Хорошо, после нескольких часов тычков и покалечений выяснили причину, по которой реквизит не определен. Очевидно, после удаления Typescripts мне нужно было повторно связать 'this', чтобы получить правильный контекст:

<ReactAutocomplete ... onChange={this.handleChange.bind(this)} ... />
...