Symfony - две формы активируются отдельно

В основном, реквизиты и состояние - это два способа, которыми компонент может знать, что и как визуализировать. Какая часть состояния приложения принадлежит государству и которая принадлежит некоторому магазину верхнего уровня, больше связана с дизайном вашего приложения, чем с тем, как работает React. Самый простой способ решения - ИМО - подумать, полезен ли этот конкретный фрагмент для приложения в целом или какая-то локальная информация. Кроме того, важно не дублировать состояние, поэтому, если какой-либо фрагмент данных можно вычислить из реквизита - он должен рассчитываться из реквизита.

Например, предположим, что у вас есть элемент управления выпадающим списком (который включает стандартный HTML-выбор для пользовательского стиля), который может: a) выбрать какое-либо значение из списка и b) открыть или закрыть (т. е. список опций, отображаемый или скрытый). Теперь предположим, что ваше приложение отображает список элементов определенного типа и ваш фильтр выпадающего списка для записей списка. Тогда было бы лучше передать значение активного фильтра в качестве опоры и сохранить открытое / закрытое состояние локально. Кроме того, чтобы сделать его функциональным, вы должны передать обработчик onChange из родительского компонента, который будет вызываться внутри элемента выпадающего списка и немедленно отправить обновленную информацию (новый выбранный фильтр) в магазин. С другой стороны, открытое / закрытое состояние может храниться внутри выпадающего компонента, потому что остальная часть приложения действительно не заботится о том, открыт ли элемент управления, пока пользователь не изменит его значение.

Следующий код не полностью работает, ему нужны css и обработка выпадающего списка щелчков / размытие / изменение событий, но я хотел бы сохранить пример минимальным. Надеюсь, что это поможет понять разницу.

const _store = {
    items: [
    { id: 1, label: 'One' },
    { id: 2, label: 'Two' },
    { id: 3, label: 'Three', new: true },
    { id: 4, label: 'Four', new: true },
    { id: 5, label: 'Five', important: true },
    { id: 6, label: 'Six' },
    { id: 7, label: 'Seven', important: true },
    ],
  activeFilter: 'important',
  possibleFilters: [
    { key: 'all', label: 'All' },
    { key: 'new', label: 'New' },
    { key: 'important', label: 'Important' }
  ]
}

function getFilteredItems(items, filter) {
    switch (filter) {
    case 'all':
        return items;

    case 'new':
        return items.filter(function(item) { return Boolean(item.new); });

    case 'important':
        return items.filter(function(item) { return Boolean(item.important); });

    default:
        return items;
  }
}

const App = React.createClass({
  render: function() {
    return (
            <div>
            My list:

            <ItemList   items={this.props.listItems} />
          <div>
            <Dropdown 
              onFilterChange={function(e) {
                _store.activeFilter = e.currentTarget.value;
                console.log(_store); // in real life, some action would be dispatched here
              }}
              filterOptions={this.props.filterOptions}
              value={this.props.activeFilter}
              />
          </div>
        </div>
      );
  }
});

const ItemList = React.createClass({
  render: function() {
    return (
      <div>
        {this.props.items.map(function(item) {
          return <div key={item.id}>{item.id}: {item.label}</div>;
        })}
      </div>
    );
  }
});

const Dropdown = React.createClass({
    getInitialState: function() {
    return {
        isOpen: false
    };
  },

  render: function() {
    return (
        <div>
            <select 
            className="hidden-select" 
          onChange={this.props.onFilterChange}
          value={this.props.value}>
            {this.props.filterOptions.map(function(option) {
            return <option value={option.key} key={option.key}>{option.label}</option>
          })}
        </select>

        <div className={'custom-select' + (this.state.isOpen ? ' open' : '')} onClick={this.onClick}>
            <div className="selected-value">{this.props.activeFilter}</div>
          {this.props.filterOptions.map(function(option) {
            return <div data-value={option.key} key={option.key}>{option.label}</div>
          })}
        </div>
      </div>
    );
  },

  onClick: function(e) {
    this.setState({
        isOpen: !this.state.isOpen
    });
  }
});

ReactDOM.render(
  <App 
    listItems={getFilteredItems(_store.items, _store.activeFilter)} 
    filterOptions={_store.possibleFilters}
    activeFilter={_store.activeFilter}
    />,
  document.getElementById('root')
);
0
задан John 15 January 2019 в 15:23
поделиться

1 ответ

Я думаю, что ваша проблема проста, если еще проблема анидирования, когда у меня была такая же проблема, это то, что я сделал:

$id = $request->get('id');

$user = $this->container->get('account')->getUserRepository()->find($id);

$form1 = $this->createFormBuilder()
->add('password', PasswordType::class, array(
    'label' => 'Enter New Password',
    'attr' => ['class'=>'form-control']))
->add('save', SubmitType::class, array(
    'label' => 'Send', 'attr' => ['class' => 'btn btn-primary action-save']
))
->getForm();

$form2 = $this->createFormBuilder()
->add('password', PasswordType::class, array(
    'label' => 'Generate New Password',
    'disabled'=> true,
    'attr' => ['class'=>'form-control']))
->add('save', SubmitType::class, array(
    'label' => 'Send',
    'attr' => ['class' => 'btn btn-primary action-save']
))
->getForm();
$form1->handleRequest($request);
$form2->handleRequest($request);
if($form1->isSubmitted() && $form1->isValid()) {

    $this->addFlash(
        'notice',
        'You successfully changed the password!'
    );

    $data = $form1->getData();

    $new_password = $data['password'];

    $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
    $new_pwd_encoded = $encoder->encodePassword($new_password);

    $oneTimePsw = '';
    $user->setPassword($new_pwd_encoded);
    $manager = $this->getDoctrine()->getManager();

    $manager->flush();
}else

    if($form2->isSubmitted() && $form2->isValid()) {

    $this->addFlash(
        'notice',
        'Password is successfully generated!'
    );

    $data = $form2->getData();

    $new_password = $data['password'];);

    $new = $this->get('member.account')->generateRandomPassword();

    $oneTimePsw = '';
    $user->setPassword($new);
    $manager = $this->getDoctrine()->getManager();

    $manager->flush();
}
return $this->render('@AdminTemplates/admin/reset_password.html.twig', array(
    'form1' => $form1->createView(),
    'form2' => $form2->createView()
));

Это должно работать, потому что пользователь не может отправить 2 формы в один раз. У меня также была проблема с методом isValid (), поэтому попробуйте проверить его.

0
ответ дан jogarcia 15 January 2019 в 15:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: