Подключите два выпадающих фильтра к одной кнопке поиска - PullRequest
0 голосов
/ 11 мая 2018

У меня есть два выпадающих списка, которые фильтруются, но они фильтруются по мере того, как вы их выпадаете и делаете выбор. У меня есть кнопка поиска, к которой я бы хотел подключить их обоих. Таким образом, вы только что увидели изменение результатов после нажатия кнопки. Я думаю, у меня есть вся необходимая логика, но я не уверен, как именно подключить кнопку примечание: я знаю, что у меня много логики в рендере, но я просто пытаюсь заставить его работать сначала

Пока это то, что у меня есть:

    constructor(props) {
        super(props);
        this.state = {
          developers: [],
          filterCountry: "All locations",
          filterSkills: "All skills"
        };
      }

      componentDidMount() {
        fetch('API')
        .then(features =>  features.json())
        .then(developers => {
          this.setState({  developers })   
        })
      }

      filterCountry(e){
        this.setState({filterCountry: e })
      }

      filterSkills(e){
        this.setState({filterSkills: e })
      }

      render() {

        let developers = this.state.developers.features   

        if (!developers ){
          return null
        }

        if (this.state.filterCountry && this.state.filterSkills) {
             developers = developers.filter( developer => { 
             return this.state.filterCountry === 'All locations' ||   
      developer.properties.continent.includes(this.state.filterCountry)
          });


             developers = developers.filter( developer => { 
             return this.state.filterSkills === 'All skills' || 
          developer.properties.skills.includes(this.state.filterSkills)
          });  
        }
   return (
         <div>
            <div>
              <ControlSelect
                onChange={this.filterCountry.bind(this)} 
                value={this.state.filterCountry}
                options={options_dd1}
              />
            </div>
            <div className="inline-block mr24">
              <ControlSelect
                onChange={this.filterSkills.bind(this)} 
                value={this.state.filterSkills}
                options={options_dd2}
              />
            </div>
            <button>Search</button>
          </div>
        <div>
          <div>
            {developers.map(developer => {
              return (
              <div key={developer.id}">
                {developer.properties.name}
                {developer.properties.description}
                {developer.properties.skills}
              </div>
          </div>
         </div>
       )}
    )}
)

любая помощь будет принята с благодарностью

1 Ответ

0 голосов
/ 11 мая 2018

Основная проблема с тем, что у вас есть, состоит в том, что, как только фильтрация завершена, невозможно вернуть первоначальный список разработчиков.Вы можете создать «оригинальный список» или разработчиков и новый filteredList, который может фактически использоваться методом рендеринга для отображения данных.

По сути, при первоначальном рендеринге ключ developers в вашемсостояние по умолчанию загружается из fetch и будет отображаться полностью.После нажатия button метод doSearch изменит состояние и удалит разработчиков.Это вызовет рендер и покажет новый отфильтрованный список.

В противном случае есть несколько незначительных вещей, о которых я прокомментировал ниже.

constructor(props) {
    super(props);
    this.state = {
      developers: [],
      filterCountry: "All locations",
      filterSkills: "All skills"
    };
  }

  componentDidMount() {
    fetch('API')
    .then(features =>  features.json())
    .then(developers => {
      this.setState({  developers })   
    })
  }

  filterCountry(e){
    this.setState({filterCountry: e })
  }

  filterSkills(e){
    this.setState({filterSkills: e })
  }

  doSearch() {
    // Create copy of state (you had a `.filtered` in your code, which doesn't make sense as developers is an array so it will have no `filtered` property unless you modified the prototype
    let developers = this.state.developers.slice()   

    // This if block is pointless, because you start with a default state in the constructor (so unless your ControlSelect have a falsy option, this will always evaluate to `true`)

    if (this.state.filterCountry && this.state.filterSkills) {
         // THis will match EITHER country OR skills. You can change to && if wanted.
         developers = developers.filter( developer => { 
         return this.state.filterCountry === 'All locations' ||   
  developer.properties.continent.includes(this.state.filterCountry) || this.state.filterSkills === 'All skills'
  || developer.properties.skills.includes(this.state.filterSkills)
      });
    this.setState({ developers })
    }
  }

  render() {
return (
     <div>
        <div>
          <ControlSelect
            onChange={this.filterCountry.bind(this)} 
            value={this.state.filterCountry}
            options={options_dd1}
            value={this.state.filterCountry}
          />
        </div>
        <div className="inline-block mr24">
          <ControlSelect
            onChange={this.filterSkills.bind(this)} 
            value={this.state.filterSkills}
            options={options_dd2}
            value={this.state.filterSkills}
          />
        </div>
        <button onClick={this.doSearch.bind(this)}>Search</button>
      </div>
    <div>
      <div>
        {/* Now the developers contains stuff that was filtered in search */}
        {this.state.developers.map(developer => {
          return (
          <div key={developer.id}>
            {developer.properties.name}
            {developer.properties.description}
            {developer.properties.skills}
          </div>
      </div>
     </div>
   )}
)}
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...