0

我似乎在创建允许复选框列表和嵌套集一起工作的表单输入时遇到了一些麻烦。

我想要的是和 bookbub 完全一样的东西:http: //i.imgur.com/PfpgSf5.jpg

现在在我的数据库中,我的结构如下:

Category table
    - id
    - name
    - parent_id

基本上,我的想法是显示 _form 上的所有内容,其中 parent_id 为 null 作为标题(无复选框),以及所有具有 parent_id 的内容作为相应标题下的复选框。

但是,如果我们正在更新用户的首选项,我可以得到的唯一解决方案似乎不允许我已经检查复选框。然而,它确实显示了我想要的东西。这是我到目前为止所拥有的:

ProfileReader 的(ProfileReader 是我的模型,可以扩展用户以保持他们的偏好)_form:

<?php
$primaryCategories = (new Category)->getPrimaryCategories();
//$selectedCategories = yii\helpers\ArrayHelper::map($model->categories, 'id', 'name');
foreach ($primaryCategories as $pc) {
  echo '<p>'.$pc->name.'</p>';
  if ($pc->subCategories) {

    //the following never fully worked. It doesn't automatically check the boxes for relations that
    //are already setup. You need to somehow use $model->categories[#] and 'id' for that to work
    //echo $form->field($model->categories[#], 'id')->label(false)
    echo $form->field($pc, 'subCategories[' . $pc->id . '][]')->label(false)
              ->checkboxList(yii\helpers\ArrayHelper::map($pc->subCategories, 'id', 'name'),
                  ['separator' => '<p>']);
  }
}
?>

ProfileReaderController:

public function actionUpdate()
{
    $model = $this->findModel(\Yii::$app->user->identity->id);
    if ($model == null) {
      $model = new ProfileReader();
      $model->user_id = \Yii::$app->user->identity->id;
    }

    if ($model->load(Yii::$app->request->post()) && $model->save()) {

      //link the categories to the pen name
      $categories = Yii::$app->request->post()['Category']['subCategories'];
      $model->unlinkAll('categories', true);
      foreach ($categories as $category) {
        if ($category) 
          foreach ($category as $c) {
            $c = (new Category)->findOne($c);
            $model->link('categories', $c);
          }
      }

      return $this->redirect(['update']);
    } else {
        return $this->render('update', [
            'model' => $model,
        ]);
    }
}

个人资料阅读器:

public function getCategories()
{
    return $this->hasMany(Category::className(), ['id' => 'category_id'])
      ->viaTable('user_category', ['user_id' => 'user_id']);
}

有谁知道我怎么能做到这一点?在 Yii2 中是否有可能使用 activeform?

4

1 回答 1

0

好的,经过几个小时我终于弄明白了。在这里发布我生成的代码,以便它可以帮助其他人。不要让我解释它,因为我自己并没有完全理解它:P

在将其投入实际环境之前对其进行一些测试也可能是一个好主意,我还没有做过任何事情。

更新动作:

/**
 * Updates an existing ProfileReader model.
 * If update is successful, the browser will be redirected to the 'view' page.
 * @param integer $id
 * @return mixed
 */
public function actionUpdate()
{
    $model = $this->findModel(\Yii::$app->user->identity->id);
    if ($model == null) {
      $model = new ProfileReader();
      $model->user_id = \Yii::$app->user->identity->id;
    }

    if ($model->load(Yii::$app->request->post()) && $model->save()) {

      //unlink the categories first to avoid duplicates
      $model->unlinkAll('categories', true);
      //link the categories to the pen name
      foreach ($model->categoriesArray as $pc) {
        if ($pc) {
          foreach ($pc as $sc) {
            $sc = (new Category)->findOne($sc);
            $model->link('categories', $sc);
          }
        }
      }

      return $this->redirect(['update']);
    } else {

      //get the categories and separate them into groups based on parent_id
      foreach ($model->categories as $c) {
        $model->categoriesArray[$c->parent_id][] = $c;
      }

      return $this->render('update', [
          'model' => $model,
      ]);
    }
}

ProfileReader 模型(必须添加一个变量):

公共 $categoriesArray;

_形式:

<label class="control-label">Categories</label>
<?php
$allCategories = (new Category)->getOrderedCategories();
foreach ($allCategories as $pc) {
  echo '<p>'.$pc['name'].'</p>';
    echo $form->field($model, 'categoriesArray['.$pc['id'].'][]')->label(false)
              ->checkboxList(yii\helpers\ArrayHelper::map($pc['subCategories'], 'id', 'name'),
                  ['separator' => '<p>']);
}
?>
于 2015-08-08T12:18:31.770 回答