Importer

Как программно создать элемент на странице в Meteor? - 3 Points

Здравствуйте! Мой вопрос является очень простым и затрагивает базовую вещь - рендеринг элементов на странице. Но к моему удивлению я уже долгое время не могу найти информацию по этому вопросу.

Я использую ReactJS как фронт-энд фреймворк.

Скажем, у меня есть страничка с простейшей формой: полем, кнопкой Добавить поле и кнопкой Отправить. Внимание вопрос: как реализовать эту самую кнопку Добавить поле? При нажатии на которую - появляется еще одно текстовое поле.

Расскажу, как я пытался решить эту задачу.

class IngredientForm extends Component {
  render() {
    return(

      <form onSubmit={this.handleSubmit.bind(this)}>

        <input type="text"/>

        { this.renderOtherInputs() }

        <input type="button" value="Add Ingredient" onClick={this.addIngredient.bind(this)}>

        <input type="submit" value="Submit Form">

      </form>
    );
  }
}

Вот код для это самой формы. При нажатии на кнопку Add Ingredient должно появиться еще одно <input type="text>.

Как же это сделать? Я знаю, что основа Метеора - реактивность, поэтому прямым образом ничего рендерить не надо. Нужно опираться на некий реактивный источник данных и изменять его. А он уже будет вызывать изменения интерфейса.

В туториалах рассматривалась всего одна ситуация - у нас есть коллеккция, нужно отобразить каждый документ из коллекции. То есть реактивный источник данных - коллекция, мы ее сворачиваем в массив, а затем для каждого элемента массива отрисовываем некий интерфейс. Что ж, я решил делать аналогично, но так как количество инпутов на странице - это локальное состояние на клиенте, то хранить это в коллекции будет неправильно. у метеора есть ответ - reactive var. имеем:

numOfIngredients = new ReactiveVar([]);

Когда нажимаем на Добавить поле, то срабатывает следующий метод:

addIngredient(e) {
    e.preventDefault();
    let newNumOfIngredients = numOfIngredients.get();
    newNumOfIngredients.push('no matter');
    numOfIngredients.set(newNumOfIngredients);
}

Ну и метод для рендеринга, оснванного на нашем реактивном массиве:

renderOtherInputs() {
  return numOfIngredients.get().map((elem) => {
    return(
      <input type="text"/>
    );
  }
}

Но код не работает. Я прописал в методе addIngredient console.log(numOfIngredients.get()) и при нажатии на кнопку добавления поля в консоль выводилось правильное поведение:

['no matter']
['no matter','no matter']
['no matter','no matter','no matter']
...

Тем не менее поле не появляется. Я пробовал и с createContainer делать, объявляя numOfIngredients = new ReactiveVar([]); там, а затем обращаясь к нему как this.props.numOfIngredients.get(). Массив заполняется, в консоль выводится, инпуты не появляются. Возможно мое решение по своей сути является неправильным и костыльным.

вопрос на анлийском

Очень надеюсь на помощь сообщества, тем более что вопрос у меня элементарный, как мне представляется. Заранее спасибо за ваши ответы !



No answers

This site uses data from stackexchange. Source