Search code examples
laraveloptimizationgrid-layoutlaravel-admin

Laravel Admin plugin, how to call a function only once for each row


I have a Laravel project with Laravel admin running on it.
On the "Users" page I'm trying to display information both from the users table and the pocket money table like so:

...

use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
use HerazikaServer\Models\User;
use HerazikaServer\Models\PocketMoney;

...

class UserController extends AdminController
{
    protected function grid()
    {
        $grid = new Grid(new User());
        // I'm trying to call this function only once for each row like so
        // $current = PocketMoney::getCurrentMonthDetails($grid->id);

        $grid->column('id', __('Id'));
        $grid->column('nickname', __('Nickname'));

        ...

        $grid->column('current pocket money period')->display(function() {
            $current = PocketMoney::getCurrentMonthDetails($this->id);
            return isset($current) ? $current->current_start_date.' '.$current->current_end_date : '';
        })->style('min-width:100px');
        $grid->column('daily objective')->display(function() {
            $current = PocketMoney::getCurrentMonthDetails($this->id);
            return isset($current) ? $current->daily_objective : '';
        });
        $grid->column('monthly objective')->display(function() {
            $current = PocketMoney::getCurrentMonthDetails($this->id);
            return isset($current) ? $current->monthly_objective : '';
        });
        $grid->column('attendance')->display(function() {
            $current = PocketMoney::getCurrentMonthDetails($this->id);
            return isset($current) ? $current->attendance.'/'.$current->monthly_objective : '';
        });
        
        ...

        return $grid;
    }
}

However I am having to call $current = PocketMoney::getCurrentMonthDetails($this->id); for every column (about 20 times total). Is there a way to call the function only once?
I tried something along the lines of getCurrentMonthDetails($grid->id);. but it obviously throws an undefined error.


Solution

  • You can try these solutions:

    1、where you start function ,you can try

    $items = PocketMoney::query()->where('...')->limit($page,$limit)->all()->keyBy('id');
    //..usage
    $grid->column('monthly objective')->display(function() use($items) {
                $current = $items[$this->id]
                return isset($current) ? $current->monthly_objective : '';
            });
    

    2、where you call $grid->column(),you can try :

    function loadPocketMoney($id){
        if(!$item = cache()->get('product_'.$id)){
            $item = PocketMoney::getCurrentMonthDetails($id);
            cache()->set('product_'.$id,$item);
        }
        return $item;
    }
    
    $grid->column('monthly objective')->display(function() use($items) {
        $current = cache()->get('PocketMoney_id')?:loadPocketMoney($this->id)
        return isset($current) ? $current->monthly_objective : '';
    });