Yii2 Gii:向自定义模板添加自动完成和 class 名称生成

Yii2 Gii : Add autocomplete and class name generation to custom template

我最近开始为 CRUD 创建自己的 Gii 模板。

现在我注意到,当使用 Gii 创建模型时,您会自动完成 table 名称,并且在 selected 之后,会自动生成模型 class 名称还有。

如何为我的 CRUD 模板实现此行为?我已经为我的模板创建了自定义 CRUD 生成器:

namespace app\templates\gii\crud\custom;

class Generator extends \yii\gii\generators\crud\Generator
{
    // ...
}

我必须包括什么:

  1. 将自动完成添加到 select 现有模型 class 以创建

  2. 的 CRUD 操作
  3. 根据之前select编辑的模型class自动生成SearchModel名称(例如app\model\CategoryModel变为app\model\CategorySearchModel)

如果只创建模板,不需要扩展生成器。您可以使用相同的 Gii 生成器。只需要在配置中附加到 gii 你的模板。创建模板描述于:https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/topics-creating-your-own-templates.md

在无法在生成器本身中包含自动完成后,我使用 Javascript 构建了一个解决方法。

重要提示:此解决方案假定您使用的是 yii 高级模板,并且正在使用来自后端应用程序的 Gii。如果不是这种情况,您将需要调整代码

首先,我在 gii/templates/crud/form.php 中包含了我的 JS 脚本,请注意,这个目的地可能与您的不同,具体取决于您设置 Gii 模板的位置。

\backend\assets\CrudAutocompleteAsset::register($this);

echo $form->field($generator, 'templateDestination')->dropDownList([
    "backend" => "Backend",
    "frontend" => "Frontend"
]);

您还需要将 public 属性 templateDestination 添加到您的 Generator class。如果您不使用高级模板,则不需要此字段和 select 字段。那时您只需要资产。如果您不知道如何使用资产,请查看 Yii2 guide about Assets

/**
 * Destination namespace of generated code for advanced yii template
 * @var string
 */
public $templateDestination = "backend";

资产 CrudAutocompleteAsset 将添加我的 js 文件。我做了一个 sample on JS fiddle

$(document).ready(function () {

    var templateDestinationSelect = $("select[name='Generator[templateDestination]']");
    var modelClassInput = $("input[name='Generator[modelClass]']");
    var searchModelClassInput = $("input[name='Generator[searchModelClass]']");
    var controllerClassInput = $("input[name='Generator[controllerClass]']");
    var viewPathInput = $("input[name='Generator[viewPath]']");

    modelClassInput.change(function () {
        var destination = templateDestinationSelect.val();
        var modelClass = $(this).val();
        var modelNs = modelClass.substr(0, modelClass.lastIndexOf("\"));
        var targetNs = destination + modelNs.substr(modelNs.indexOf("\"));
        var modelClassName = modelClass.substr(modelClass.lastIndexOf("\") + 1);
        var modelViewName = modelClassName.replace(/([a-z])([A-Z])/g, '-').toLowerCase();

        var modelSearchClass = modelNs + "\" + modelClassName + "Search";
        searchModelClassInput.val(modelSearchClass);

        var controllerClassName = targetNs.replace("models", "controllers") + "\" + modelClassName + "Controller";
        controllerClassInput.val(controllerClassName);

        var viewPath = "@app/../" + destination + "views/" + modelViewName;
        viewPathInput.val(viewPath);
})