Laravel保存雄辩模型的有序列表

问题描述 投票:12回答:3

我正在创建食物菜单,管理员可以通过拖放来对其进行订购/分类。此菜单包含多个类别(ProductCategory)和产品(Product)。

我在客户端使用HTML5Sortable允许嵌套d&d。标记非常简单:

<div class="categories">
    @foreach($categories as $category)
    <div class="category">
        @foreach($category->products as $product)
        <div class="products">
            <div class=""product" data=id="{{ $product->id }}">
                 {{ $product->name }}
            </div>
        </div><!-- /products !-->
        @endforeach
    </div><!-- /category !-->
    @endforeach
</div>

以及相应的javascript:

$('.categories').sortable({
    items: '.category'
});
$('.products').sortable({
    items: '.product'
});

// Will be called when the user is done repositioning the products and categories
function getOrderedList() {
    var data = {};

    $('.categories').find('.category').map(function(i) {
        var category = $(this);
        data[i] = {};
        data[i].id = category.data('id');
        data[i].products = category.find('.product').map(function() {
            return $(this).data('id');
        }).get();
    });

    data = JSON.stringify(data); // Send data to server
}

函数getOrderedList将向JSON字符串发送回Laravel,其中包含已排序的类别ID和产品ID:

{"0":{"id":1,"products":[2,3,1,4,5,6,7,8,9,10]},"1":{"id":2,"products":[11,12,13,14]},"2":{"id":3,"products":[15,16,17,18]}}

我将如何在后端进行这项工作?我想我必须将此数组存储在数据库中的某个位置,然后通过ID查找并排序模型?

简而言之:什么是用于分类(嵌套)模型(在Laravel中)的干净灵活的解决方案?

laravel model drag-and-drop eloquent sorted
3个回答
7
投票

一个常见的约定是重量,在产品表上添加一个名为(Int)Weight的字段,该字段用于定义商品的顺序。

一旦顺序发生更改,您只需更新重量字段。

检索项目时,按重量对它们进行排序。

它变得类似于数组

Id        Name            Weight
01        'product 1'     2
02        'product 2'     0
03        'product 3'     1

当您按重量订购时得到]

product 2
product 3
product 1

它类似于数组,因为

$products[0] = 'product 2'
$products[1] = 'product 3'
$products[2] = 'product 1'

请注意,如果您想使其更加动态

,则可以创建一个可以满足多个模型的多态模型。

请参阅https://laravel.com/docs/5.1/eloquent-relationships#many-to-many-polymorphic-relations

多态关系示例

创建表权重

(迁移示例)
$table->increments('id');
$table->integer('value');
$table->integer('weightable_id')->unsigned();
$table->string('weightable_type');

创建模型重量

class Weight extends Eloquent
{
    public function weightable()
    {
        return $this->morphTo();
    }
}

现在与其他任何型号一起使用

class Products extends Eloquent
{
    ...
    public function weight()
    {
        return $this->morphOne(Weight::class);
    }
}

这样,您可以将该方法添加到所需的任何模型中,然后就可以对模型进行排序。

P.S。确保使用它的任何模型在创建模型后立即创建该关系

我不推荐这种方法,如果您在Products表中明确定义权重字段,这会更好,我知道您希望代码动态化多少,但是一切都是有代价的

性能下降,一旦建立了多态关系,要可视化代码就不容易了,它更像是开始使用Jumps而不是Functions


2
投票

首先,您生成的JSON不应是键只是数组索引的对象。相反,它应该是看起来像这样的对象数组:


0
投票

我只是使用此库实现此行为:https://github.com/spatie/eloquent-sortable

© www.soinside.com 2019 - 2024. All rights reserved.