【问题标题】:Yii2: Status 'enabled' & 'disabled' helper function - dynamic useYii2:状态“启用”和“禁用”辅助功能 - 动态使用
【发布时间】:2016-08-04 11:47:00
【问题描述】:

我想将 2 个函数组合在一起,以整合代码,并根据其使用方式进行动态化。我不知道这是否可能。

首先,让我们列出基本用途。在我的示例中,我有 Post 和 PostCategory 模型(并构建了 CRUD)。您创建一个类别,然后创建一个新帖子并将其分配给该类别。帖子可以是enableddisabled。从本质上讲,您可以创建一些新帖子,并且在您准备好之前让最终用户无法查看它们。一个用例是滴灌系统,您可以在其中添加 100 个帖子,并每隔 x 天切换到 enabled。这超出了本文的范围。

views\post\_form.php

<div class="post-form">

    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'category_id')->dropDownList(
            $model->getPostCategoryConst(),
            ['prompt'=> '- Category -']
        )->label('Category')
    ?>

    <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'text')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'status')->dropDownList(
        $model->getPostStatusConst(),
        ['prompt'=> '- Status -']
    ) ?>

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

注意category_idstatus 的下拉列表以及它们调用的函数

\common\models\Post.php

const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;

public function getCategory()
{
    return $this->hasOne(PostCategory::className(), ['id' => 'category_id']);
}

/* -- Added -- */

public function getPostCategoryConst()
{
    return ArrayHelper::map(PostCategory::find()->orderBy('name DESC')->all(), 'id', 'name');
}

public function getPostStatusConst()
{
    return [
        self::STATUS_DISABLED => 'Disabled',
        self::STATUS_ENABLED => 'Enabled',
    ];
}

现在这工作得很好 :) 但是,我不喜欢像在 getPostStatusConst() 中那样使用 get,因为它不像 $model-&gt;postStatusConst 那样被访问,类似于与“getter”的关系。

不过,我也想将它们用作“吸气剂”。在索引和视图中,最好也调用相同的函数。而不是返回一个数组,而是返回一个“好名字”,例如“启用”或“禁用”

为此,我不会重命名函数,因为我不想增加任何混乱。

views\post\view.php

<?= DetailView::widget([
    'model' => $model,
    'attributes' => [
        'id',
        'category.name',
        'name',
        'text:ntext',
        'postStatusConst',  // <-- Calls getPostStatusConst()
        'created_at:datetime',
        'updated_at:datetime',
    ],
]) ?>

注意postStatusConst 与我们在_form 中用于创建操作的函数相同。在 _form 中,它需要为下拉列表返回一个数组。在我们看来,它只需要返回一个好听的名字,例如EnabledDisabled


我试过了

我在 Post 模型中尝试了这个功能:

public function getPostStatusConst()
{
    if ( isset($this) ) {
        return ($this->status === self::STATUS_ENABLED) ? 'Enabled' : 'Disabled';
    }

    return [
        self::STATUS_DISABLED => 'Disabled',
        self::STATUS_ENABLED => 'Enabled',
    ];
}

这显然没有用 :) 我没想到会这样,因为我知道$this 在一个类中引用了它自己。它只是显示了我的目标。

在关系中,hasOne() 似乎知道我们是将其用作直接调用 (Post::getCategory) 还是内联 ($model->category->name)..

问题

是否可以让getPostStatusConst() 做同样的事情?用作$model-&gt;postStatusConst 可以很好地显示EnabledDisabled,或者用作Post::getPostStatusConst() 来获取下拉列表。

【问题讨论】:

    标签: php yii2 yii2-advanced-app yii2-model


    【解决方案1】:

    这是可能的,但真的不值得对代码进行所有更改。您将不得不重写魔术__get() 方法并考虑某种方式在一个结构中存储和访问两个返回。

    我会将getPostStatusConst() 保留为当前状态名称,并在下拉列表的状态列表中添加其他方法(甚至是静态方法)。

    【讨论】:

    • 感谢您的宝贵时间。我同意,你说的不值得。在过去的项目中,我使用了 2 个单独的功能。随着我的进展,我尝试将事情做得更好、更酷、更高效:) 我想我在某个地方读到了关系,例如用 Gii 构建的关系(例如 hasOne())知道它的使用方式之间的区别。我浏览了代码,但没有跳过很​​多圈子,因为每个文件都引用另一个文件,又引用另一个文件。
    • 其实我真的很接近 :) 我解决了!当我允许我(我认为是 2 天)时,我会标记我的答案。在那之前,我对任何其他解决方案持开放态度。也许是一些潜在的 Yii 功能,或者更好的方法。
    • 这是一个不错的 hack,但会根据 PHP 版本和配置触发错误/警告。在回答时,我正在考虑与 Yii 2 中的关系方法和属性相同的解决方案。
    • 根据我的其他评论,它确实会引发错误。我在想同样的事情,它适用于关系。这应该是可复制的。我浏览了源代码,但找不到他们将其拉下来的地方。
    【解决方案2】:

    我已经很接近了。我不是在想 PHP OOP 行,而是更多 Yii。谷歌搜索了几下,我拍了拍我的额头。使用框架时,您有时甚至会忘记用 PHP 编写代码;)

    public function getPostStatus()
    {
        if ( isset($this) && get_class($this) == __CLASS__) {
            // not static
            return ($this->status === self::STATUS_ENABLED) ? 'Enabled' : 'Disabled';
        }
    
        return [
            self::STATUS_DISABLED => 'Disabled',
            self::STATUS_ENABLED => 'Enabled',
        ];
    }
    

    我重命名了这个函数,让它更有意义。

    它无处不在。让我们看看我的 CRUD 的索引:

    views\post\index.php

        <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
    
            'id',
            'category.name',
            'name',
            //'text:ntext',
            'postStatus',
            // 'created_at',
            // 'updated_at',
    
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
    

    views\post\view.php

    <?= DetailView::widget([
        'model' => $model,
        'attributes' => [
            'id',
            'category.name',
            'name',
            'text:ntext',
            'postStatus',
            'created_at:datetime',
            'updated_at:datetime',
        ],
    ]) ?>
    

    views\post\_form.php

    <?= $form->field($model, 'status')->dropDownList(
        Post::getPostStatus(),
        ['prompt'=> '- Status -']
    ) ?>
    

    所有这些情况似乎都可以正常工作。有人遇到过这种不起作用的情况吗?

    【讨论】:

    • 你没有收到错误Strict standards: Non-static method Post::getPostStatus() should not be called statically吗?根据您的配置和/或 PHP 版本,您的日志(更糟糕的是,您的输出)可能会变得混乱。
    • 您的权利。几周前我重新安装了 xampp,忘记将错误报告更改为 E_ALL。它不包括严格和弃用。所以虽然这确实工作得很好,但严格会抱怨它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    相关资源
    最近更新 更多