sergeyugai/backpack-fields-as-classes

该软件包允许在Laravel Backpack中添加字段/列等,同时将其作为类使用

0.4.2 2020-07-20 13:50 UTC

This package is auto-updated.

Last update: 2024-09-26 04:13:39 UTC


README

这是一个针对Laravel backpack的即插即用解决方案,用于将列/字段声明通过数组替换为面向对象的方法。这允许您的IDE帮助您编写这些内容。

本版本与Backpack 4.1及以上版本兼容;对于旧版本的Backpack,请使用本软件包的0.3.*版本。

TLDR:使用本软件包,您可以编写如下Backpack代码

use Backpack\CRUD\app\Library\CrudPanel\CrudPanel;

public function setupOperation() 
{
    // option 1 (via CrudPanel)
    CrudPanel::textField('user')->suffix('...etc');

    // option 2 (via builder method)
    TextField::name('user')->prefix('1.'); 
    TextField::make('field_name', 'optional_label')

    // option 3 (via constructor)
    (new TextField('user', 'some label'))->chained_methods...

    // option 4 (older ways):
    $this->crud->addFields([
        TextField::make('field_name', 'optional_label')->other_chained_methods...,
        (new TextField('title'))->prefix('1.')
    ]); 
    
    // Has methods generated for all backpack fields and columns!
    // Widgets not supported yet.
}

优点

  • 无需修改现有代码并且可以与现有定义一起使用。
  • 完全兼容于Fluent语法(更多信息请参阅此处
  • 提供多种声明字段和列的方法 - 选择您喜欢的方法
  • 您可以通过使用作为当前Backpack的即插即用功能的字段集合来使您的代码更加DRY。

安装

composer require sergeyugai/backpack-fields-as-classes

如何使用

本软件包中有3种类型的类

  • 字段
  • 字段集合

我将解释它们的用法,但首先让我传达基本想法 - 而不是像这样创建数组

$this->crud->addField(
    [ // Text
        'name' => 'title',
        'label' => "Title",
        'type' => 'text',

        // optional
        //'prefix' => '',
    ]);

您使用提供的类来构建具有相同配置的对象(如上面的数组),但而不是设置数组键,您调用对象方法并传递值,如下所示

$this->crud->addField(
    TextField::make()->name('title')->label('Title')->prefix('whatever')
);

// OR just directly without any CRUD calls:
TextField::make()->name('title')->label('Title')->prefix('whatever')

// Or by using CrudPanel:
\Backpack\CRUD\app\Library\CrudPanel\CrudPanel::addressAlgoliaField('field')

因此,每个字段类型和列类型都有一个类。

字段

您可以通过创建新对象或调用静态方法make()来创建字段。它们接受两个可选方法 - 字段名称和字段标签。

通过构造函数

class SomeCrudController extends CrudController
{
    public function setup()
    {
        //...
        $this->crud->addField( (new TextField())->...)
        $this->crud->addField( (new TextField('field name can be passed'))->...)
        $this->crud->addField( (new TextField('field name can be passed', 'field label can be passed'))->...)
        //...
    }
}

通过make()name()

class SomeCrudController extends CrudController
{
    public function setup()
    {
        //...
        TextField::name('field name must be passed')->
        TextField::make('field name must passed')->...
        TextField::make('field name must be passed', 'field label can be passed')->...
        //...
    }
}

之后,您可以进行各种方法调用的链式操作。例如,您知道文本字段可以具有"prefix"键 - 您可以像这样链式调用

TextField::make('title', 'Title')->prefix('whatever')

在这个例子中,您可以省略'Title',因为Backpack将根据名称自动提供此标签。

TextField::make('title')->prefix('whatever')

或者,如果您想要更清晰的了解,您可以完全不对构造函数进行传递,而是单独传递名称

TextField::make()->name('title')->prefix('whatever')

您可以调用任何方法,甚至是文档中未提及的方法,即使该方法在我的类中不存在。这样做的原因是,如果您决定使用自定义字段,您可以像这样创建自己的声明

    Field::make()
            ->name('my_custom_field')
            ->label('My field:')
            ->type('my_field_type')
            ->value('whatever')
            ->someBoolParam(true)
            ->someConfig(['extra' => function() { echo "hi"; }])

这将转换为Backpack可以理解的数组格式

            'name' => 'my_custom_field',
            'label' => 'My field:',
            'type' => 'my_field_type',
            'value' => 'whatever',
            'someBoolParam' => true,
            'someConfig' => ['extra' => function() { echo "hi"; }]

然而,如果您编写自定义字段,您可以创建新类并声明您的字段可用的方法

class MyCustomField extends Field
{
    ... for possible method implementations, just check out source code of other
    ... fields and find the ones that better fit you for bools and stuff
}

列的行为与字段完全相同

   ...
    TextColumn::make('title')->limit(60)
   ...

如果您使用$this->crud引用,您必须在最后添加asArray()。

$this->crud->addColumn(
    TextColumn::make('title')->limit(60)->asArray()
)

如果这个软件包变得流行,我将提交一个PR到Backpack来修复这个问题,这样就不会有"asArray()"了,但现在就是这样。

字段集合

我认为Laravel Backpack代码的可读性最大的问题之一是,有时有很多重复的内容 - 例如,如果您使用制表符,您可能会有很多重复的行,如下所示

    'tab' => 'some_tab'

或者您可能想以类似的方式配置数值字段,或者...您可能想做的任何事情。

所以你可以将这些字段放入一个特殊的集合中(或者使用该集合的构建方法创建它们——我会展示两个例子),然后调用该集合上的方法——这些方法将应用于每个字段。

从现有字段创建集合

$myTextField = TextField::make('title');
$myNumField = NumericField::make('page_num');

$this->crud->addFields(
   FieldsCollection::make([
        $myTextField, $myNumField
   ])->toArray()
);   

创建特定类别的字段(在这个例子中,我创建了两个NumericField字段的字段)

$this->crud->addFields(
   FieldsCollection::make()->addFieldsOfType(NumericField::class, [
      'min_price_of_item' => 'Min price of item', // 'min_price_of_item' is name, 'Min price of item' is label
      'max_price_of_item' => 'Max price of item',
   ])->toArray()
);   

然后你可以应用任何相同的属性

$this->crud->addFields(
   FieldsCollection::make()->addFieldsOfType(NumericField::class, [
      'min_price_of_item' => 'Min price of item', // 'min_price_of_item' is name, 'Min price of item' is label
      'max_price_of_item' => 'Max price of item',
   ])->prefix('$')->attributes(['step' => '5'])->tab('Pricing')->toArray()
);   

这就完成了——这个集合知道如何将其内容表示为Laravel Backpack的CRUD。

你可以混合匹配不同类型的FieldsCollections,但控制具体字段是否支持传递的参数取决于你(尽管通常这不是问题,因为调用任何字段的非现有方法都是安全的)。

你获得的额外好处

除了有良好的面向对象声明、IDE自动完成和快速跳转到类以获取更多信息的能力之外,还有一些其他的事情

$field作为对象

如果你为字段编写了自定义视图,你知道你需要在那里处理数组。然而,如果你使用这些类,你的$field变量也可以作为对象使用,这允许你在这里实现自己的辅助方法。

添加你自己的方法!

你不必仅限于为自定义视图编写辅助方法——你可以按你喜欢的方式扩展类并实现所有 sorts of其他辅助方法、语法糖等。

更高的可读性

为了提高可读性,我建议做一些像这样的事情

class SomeCrudController extends CrudController
{
    public function setup()
    {
        //...
        $this->crud->addField($this->titleField())
        //...
    }
    
    public function titleField(): TextField {
       return (new TextField('title))->label('...')->prefix(..);
    }
}

这样,你可以通过注释/取消注释一个方法调用来添加/删除字段,并且你也得到“一个方法负责一个字段声明”,这对于某些具有复杂逻辑的方法可能很聪明。这也给你的crud设置提供了更好的概述。当然,这只是个人口味的问题。

理由

嗯,为了以下好处

  1. IDE自动完成——这确实是最大的原因
  2. 可读性可以改进(因为你可以在子类中添加一些糖语法)
  3. 当你为字段构建自己的视图时,你可以使用作为对象的$field,而不是数组,因此你可以在这里实现自己的辅助方法。
  4. 字段的自动生成——是的,我们自动生成了所有字段/列类,我没有手动编写实际的字段。关于这一点——下面。

更多讨论在这里 - https://github.com/Laravel-Backpack/CRUD/issues/2604

代码生成?

是的,这相当重要——几乎所有的字段和列都是从Backpack的文档中自动生成的。这给我们带来了速度上的好处(如果我要手动编写每个字段/列类,我会杀死自己),但有可能某些字段没有很好地生成——要么通过发出PR来帮助我,要么在你的项目中扩展字段并实现/覆盖方法。

Backpack的字段和列文档在格式上相当一致(因此代码生成才成为可能);如果未来的Backpack作者/贡献者使其100%一致,这可能会极大地提高这个包的质量。

无论如何,你可以自己尝试自动代码生成。要调用它,你只需要发出

php generate.php

这样,例如,你可以用Backpack的老版本替换字段,即——如果文档有更多或更少的相同格式。生成器本身在MainGenerator.php文件中,它逐行读取文档,充当状态机并收集有关字段的信息。

支持什么?

目前我们支持字段。随着列表的增长,我会在这里添加更多内容。

测试?

测试很少;如果这个变得流行,并且Backpack文档得到了更好的结构,那么我会添加一些测试,这些测试可能也会自动生成(至少部分)所有这些字段和列。

贡献

目前这个项目只是我的一个助手,但欢迎提交拉取请求。

你可以帮忙做以下事情

  1. 文档(添加笑话,移除笑话,使内容更清晰)
  2. 测试
  3. 扩展功能
  4. 增加语法糖

你也可以通过为 backpack 的文档提交拉取请求来间接帮忙,这样可以提高此包的代码生成质量 - 这样你既帮助了这里,也帮助了 backpack。