1

这是一个最佳实践问题,而不是特定问题。我对 MVC 方法和 Yii 相当陌生,并且已经在应用程序上开发了一段时间。我一直在讨论最佳实践以及将什么放入哪个文件(控制器、模型、视图、助手等),但是我还没有找到任何具体的示例。

我目前有这样的电话:Model::function()在我的视图文件中以及像这样的检查$var = app()->request->getParam(value, false);

我在我的控制器文件中有调用,例如 Model::function() 和 Model::model()->scope1()->scope2()->findAll() 我也认为我的控制器文件有点厚,但不是确定如何以及在何处放置一些臃肿,我一直在阅读有关 DRY 的内容,我认为可以说我并没有完全干燥我的代码。你能否给我一个更清晰的图片,让我更清楚地了解去哪里,以及建议或原因:) 感谢任何建议,在此先感谢。

这是视图文件中的示例调用

<?php
$this->pageTitle = 'Edit Action';
$this->subTitle = '<i>for</i> <b>' . Vendors::getName($_GET['vendor']) . '</b>';
?>

<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model' => $model)); ?>
</div>

getName 是我在模型中的函数,这是在视图中调用函数的好方法吗?

另一个示例视图文件:

<div class="wrapper">
    <?php 

    if($this->action->id != 'create') {
        $this->pageTitle = "New Media Contact";
         echo $this->renderPartial('_form', array('model'=>$model));
    } else {
        $this->pageTitle = "New Vendor";
         echo $this->renderPartial('_form', array('model'=>$model));
    }
    ?>
</div>

$model 在控制器中设置了类型......同样的问题......可以这样做......更清洁......?在 MVC 和可重用性/DRY 方面更好?

编辑 在阅读了这里的一些回复之后,尤其是。@Simone 我重构了我的代码,并想分享它现在的样子......

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

    // Get and Set request params
    $model->type = app()->request->getParam('type', Vendors::VENDOR_TYPE);
    $vendorsForm = app()->request->getPost('Vendors', false);
    // Uncomment the following line if AJAX validation is needed
    $this->performAjaxValidation($model);
    if ($vendorsForm) {
        $model->attributes = $vendorsForm;
        if ($model->save())
            $this->redirect(array('/crm/vendors', array('type' => $model->type)));
    }
    $model->categories = Categories::getAllParents($model->type);
    $this->pageTitle = 'New ' . Lookup::item('VendorType', $model->type);
    $this->render('create', array(
        'model' => $model,
    ));
}

和视图 create.php

<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model));?>

感谢所有回复

4

4 回答 4

3

我对 Yii 框架不太熟悉,但可以就你提到的一些具体事情提供一些建议:

不要太拘泥于“最佳实践”,因为所有设计模式 MVC 都可以实现,并且在某些情况下,不同的开发人员可以以多种不同的方式进行解释。那么这是什么意思?这意味着尽可能多地阅读 MVC,然后只需试一试 :o) 当你遇到问题时,你很快就会发现哪些插槽在哪里以及为什么会出现问题(通常是“这在哪里做的”属于,控制器或模型?...'。

至于去哪里,您可以谷歌/搜索stackoverflow或阅读无数书籍,许多关于应该做什么和去哪里的解释,但是从您提供的代码片段中,我建议:

查看文件:(除非这是 Yii 特定的东西)在我看来你的查看文件有点脏。您正在直接与模型交谈(这实际上是 MVC 的经典方法,而不是某些 PHP 应用程序采用“控制器是唯一允许与模型交谈”的方法),但您的视图似乎正在尝试获取请求数据直接,对我来说,这不应该在视图附近的任何地方。控制器应该处理请求,使用模型进行验证,然后将输出传递到视图中。

模型:从小片段来看,这似乎还可以,但总的来说,要记住的重要一点是模型!= 数据库(尽管有人建议它是)。

控制器:从您的代码段中看起来还是不错的,但是要解决控制器中的膨胀问题,如果没有看到您的控制器之一,就很难提供建议。始终值得考虑的一件事是服务的使用。基本上,一项服务可以通过封装大量重复/复杂的模型内容来大大简化您的控制器。因此,无需在控制器中调用单独的验证和持久性模型,您只需实例化一个服务类,这可能只是调用一个方法的情况(通常返回一个布尔值以向控制器指示操作的成功或失败)然后你的控制器只需要处理它最擅长(并且应该只做)应用程序的流程(即重定向到另一个页面,显示错误等)。

于 2012-05-31T23:30:38.933 回答
2

我将向您展示一个重构代码的示例。这是你的代码

<div class="wrapper">
    <?php 
        if($this->action->id != 'create') {
            $this->pageTitle = "New Media Contact";
            echo $this->renderPartial('_form', array('model'=>$model));
        } else {
            $this->pageTitle = "New Vendor";
            echo $this->renderPartial('_form', array('model'=>$model));
        }
    ?>
</div>

第一个问题是:为什么要用renderPartial 写两次同一行?第一次重构:

<div class="wrapper">
<?php
    if($this->action->id != 'create') {
        $this->pageTitle = "New Media Contact";
    } else {
        $this->pageTitle = "New Vendor";
    }
    echo $this->renderPartial('_form', array('model'=>$model));
?>
</div>

现在第二步:

<?php $this->pageTitle = $this->action->id != 'create' ? "New Media Contact" "New Vendor"; ?>

<div class="wrapper">
 <?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
</div>

FOR ME 更具可读性。我觉得有很多最佳实践。但可能会成为在不良环境中使用的不良做法。所以... 重写代码真的有用吗?对我来说是的!因为我的目标是代码的可维护性。易于阅读,易于管理。但是你需要找到你的标准或你的团队标准。另外,我更喜欢在控制器中移动任何类型的逻辑。例如,我可以在控制器中设置默认 pageTitle 并在 actionCreate 方法中重新定义它:

class SomeController extends CController
{

    public $pageTitle = "New Vendor";

    function actionCreate ()
    {
        $this->setPageTitle("New Media Contact")
        $this->render('view');
    }

}

我的视图文件将变为:

<div class="wrapper">
    <?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
</div>

我想我们要明白事物的责任:视图只是一个视图。

于 2012-06-01T04:13:15.447 回答
0

只需将视图视为显示数据的组件。它不应该进行数据库调用、与模型交互、创建新变量(或很少)等。如果您想进行检查或使用某些数据创建 HTML 块等,请为此目的使用帮助程序。
视图将显示的数据将来自控制器。

控制器是在你的应用程序中完成大部分工作的大师:它会回答请求,在需要时向模型询问数据,将数据传递给视图并呈现它等等。

在您的第一个示例中,只需将Vendors::getName($_GET['vendor'])变量保存在控制器中,然后将其传递给视图。
此外,如果您不需要 allmodel的数据,请不要传递整个对象。

关于您的第二个片段,首先您可以将echos 从if语句中移出,因为它们是相同的。
一件好事是if ($this->action->id != 'create')在您的控制器中进行检查,并为您的视图提供一个简单的布尔值:

if ($this->action->id != 'create') { // not sure if $this->action->id would remain the same, I don't know Yii
    $media = true;
    // or 
    // $page = 'media';
} else {
    $media = false;
    // or 
    // $page = 'vendor';
}

并根据控制器返回的值渲染部分。

于 2012-05-31T23:18:15.290 回答
-3

在我看来,没有“最佳实践”。只要您不是在团队中工作或希望将您的脚本作为开源发布(必须有数十人使用它),就可以根据您的喜好和需要使用该框架。即使您与其他人一起编写代码,也没有“上帝赐予”的规则。

如果您“真的被允许”在视图中使用静态函数,那么还有比问题更重要的事情。

于 2012-05-31T23:00:43.537 回答