首页 文章

Yii2:listbox的正确语法?

提问于
浏览
1

我正在尝试使用列表框并使用以下语法进行多选,这是行不通的 .

<?= $form->field($model, 'weekday')->listBox([
       'monday'=>'Monday',
        'tuesday'=>'Tuesday',
        'wednesday'=>'Wednesday',
        'thursday'=>'Thursday',
        'friday'=>'Friday',
        'saturday'=>'Saturday',
        'sunday'=>'Sunday'],['multiple'=>true,'size'=>7])

            ?>

我能够在列表框中进行多选,但它返回一个空值 . 如果我正在接受 multiple'=>true 的部分,那么它将返回正确的值,但之后我无法进行多选 .

我在这做错了什么?

谢谢 .

约会模型中的相关代码.php

公共职能规则(){

return [
        [['appointment_date'], 'safe'],
        [['priority', 'weekday'], 'string', 'max' => 20]
    ];

}

控制器代码:

public function actionCreate()
    {
        $model = new Appointment();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

在aragachev的答案中更新建议代码后我得到的错误的堆栈跟踪

Getting unknown property: app\models\Appointment::weekday 1.在E:\ wamp \ www \ HospitalErp \ vendor \ yiisoft \ yii2 \ base \ Component.php第143行134135136137138139140141142143144145146147148149150151152

foreach ($this->_behaviors as $behavior) {
            if ($behavior->canGetProperty($name)) {
                return $behavior->$name;
            }
        }
    }
    if (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);//line 143
    }
}

/**
 * Sets the value of a component property.
 * This method will check in the following order and act accordingly:
 *
 *  - a property defined by a setter: set the property value
 *  - an event in the format of "on xyz": attach the handler to the event "xyz"

2. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\db\BaseActiveRecord.php – yii\base\Component::__get('weekday') at line 247
3. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\helpers\BaseArrayHelper.php – yii\db\BaseActiveRecord::__get('weekday') at line 190
4. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\widgets\DetailView.php – yii\helpers\BaseArrayHelper::getValue(app\models\Appointment, 'weekday') at line 209
5. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\widgets\DetailView.php – yii\widgets\DetailView::normalizeAttributes() at line 123
6. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\base\Object.php – yii\widgets\DetailView::init()

1 回答

  • 2

    原因是StringValidator附加到模型规则中的 weekday 属性:

    [['priority', 'weekday'], 'string', 'max' => 20],
    

    由于 multiple => true 选项,您正在接收数组,而不是字符串(即使在一次选择的情况下) . 它根本没有通过验证 .

    Yii 2中没有内置的数组验证器 .

    1) 因为您需要多个选择,我建议您将 weekday 重命名为 weekdays .

    2) 我建议将工作日列表放在单独的方法中:

    public static function getWeekdaysList()
    {
        return [
            'monday' => 'Monday',
            'tuesday' => 'Tuesday',
            'wednesday' => 'Wednesday',
            'thursday' => 'Thursday',
            'friday' => 'Friday',
            'saturday' => 'Saturday',
            'sunday' => 'Sunday',
        ];
    }
    

    3) 创建inline validator,例如,像这样:

    public function validateWeekdays ($attribute, $params)
    {
        $label = '«' . $this->getAttributeLabel($attribute) . '»';
    
        // Checking if it's array first
        if (is_array(!$this->$attribute)) {    
            $this->addError($attribute, "$label must be array.");
    
            return;
        }
    
        $allowedWeekdays = array_keys(static::getWeekdaysList());
    
        // Checking if every selection is in list of allowed values
        foreach ($this->$attribute as $weekday) 
        {
            if (!in_array($weekday, $allowedWeekdays)) {
                $this->addError($attribute, "$label - $weekday is not in allowed list");
    
                return;
            }
        }
    }
    

    offical guide中阅读有关内联验证器的更多信息 .

    4) 在模型规则中将其附加到 weekdays

    ['weekdays', 'validateWeekDays'],
    

    如果您不想验证 weekDays ,则应将其明确标记为安全属性,以便使用其他属性进行大规模分配:

    ['weekdays', 'safe'],
    

    5) 在视图中,您可以将代码简化为:

    <?= $form->field($model, 'weekdays')->listBox(Appointment::getWeekdaysList(), [
        'multiple' => true,
        'size' => 7,
    ]) ?>
    

    还有一个小小的评论 - weekday这是一个工作日,不包括周六和周日 . 更正确的形式是一周中的几天 .

相关问题