ElisDN/yii2-composite-form

Model::loadMultiple в load()

coderovich opened this issue · 4 comments

Здравствуйте.
То ли лыжи не едут, то ли баг.

  1. Задаем в конструкторе ProductCreateForm свойство $value немного не как у Вас, а через перебор связей:
public function __construct(Model $model = null, $config = [])
    {
        $this->values = array_map(function (Relation $relatedModel) {
                return new RelationForm($relatedModel);
            }, $model->relationName); // предположим тут 2 прилинкованных entities
        parent::__construct($config);
    }
  1. В форме делаем возможность добавлять новые RelationForm к уже имеющимся (я о банальном плюсике например). Жмем плюсик, заполняем появившиеся поля/поле для новой связи. Субмиттим.

  2. При Post'e этого запроса в контроллер в CompositeForm'е сюда:
    $success = Model::loadMultiple($form, $data, $formName === null ? null : $name) || $success;
    попадет переменная $form, где будут наши 2 объекта из примера в п.1
    При этом в переменную $data прилетит массив $_POST[RelationForm][], где кол-во элементов будет уже больше двух. LoadMultiple в цикле пройдется только по 2ум объектам из $form и 1 элемент из $_POST потеряется.

Это я что-то не так делаю? Или CompositeForm просто не предназначена для таких ситуаций? Спасибо.

А что мешает посчитать кол-во переданных post[RelationForm] и создать форму с нужным кол-вом RelationForm. В конструктор добавляйте переменную и по её значению n-ок кол-во форм. Если переменная пустая, то тянуть из базы.

public function __construct($countRelations, Model $model = null, $config = [])

А что мешает посчитать кол-во переданных post[RelationForm] и создать форму с нужным кол-вом RelationForm. В конструктор добавляйте переменную и по её значению n-ок кол-во форм

Очень громоздко получается, вот пример

public function actionCreate($id) {
    $model = new SomeModel();
    $form = new ProductCreateForm($model, count(Yii::$app->post((new RelationForm())->formNаme(), [])));
}

И таких моделей как RelationForm может быть много, эту функциональность думаю можно вынести в load

А что мешает посчитать кол-во переданных post[RelationForm] и создать форму с нужным кол-вом RelationForm. В конструктор добавляйте переменную и по её значению n-ок кол-во форм

Очень громоздко получается, вот пример

public function actionCreate($id) {
    $model = new SomeModel();
    $form = new ProductCreateForm($model, count(Yii::$app->post((new RelationForm())->formNаme(), [])));
}

И таких моделей как RelationForm может быть много, эту функциональность думаю можно вынести в load

Разобрались как это красиво и безболезненно сделать?

Разобрались как это красиво и безболезненно сделать?

Полностью красиво не получилось, плюс только в том, что все скрыто в форме, на проекте делал так:

class GameForm extends CompositeForm {
	public function __construct(Game $game= null, $config = []) {
		....

		$this->broadcasts = [];
		$this->broadcastFormName = (new BroadcastForm)->formName();

		parent::__construct($config);
	}

	protected function internalForms() {
		return ['broadcasts'];
	}
	public function loadBroadcasts($data) {
		$output = [];
		foreach (ArrayHelper::getValue($data, $this->broadcastFormName, []) as $key => $val) {
			$output[$key] = new BroadcastForm();
		}
		$this->broadcasts = $output;
		return $output;
	}
}

Ну и в классе автора в load() внес проверку

public function load($data, $formName = null) {
		$success = parent::load($data, $formName);

		foreach ($this->_forms as $name => $form) {
			// custom loader fot internal forms
			if ($this->hasMethod('load' . $name))
				$form = $this->{'load' . $name}($data);
			
			...
		}
		
		return $success;
	}

Так же уже позже была идея сделать конфигурируемый internalForms

protected function internalForms() {
	return [
		'broadcasts' => [
			'class' => $this->broadcastFormName,
			'dynamicLoad' => true,
		]
	];
}

Может сделаю форк всем на радость, если окажется удобным в использовании