在Laravel Nova中,是否有一种方法可以允许对由函数调用填充的列进行排序?

huangapple go评论58阅读模式
英文:

Is there a way in Laravel Nova to allow sorting on a column which is populated by a function call?

问题

我尝试允许Nova Lens中的一个填充列可以进行排序。填充我的"Months Remaining"列的根数据来自在镜头初始化期间调用的函数以访问API。

出于某种原因,我要么可以填充列的值,要么可以排序,但不能同时实现两者。您知道我漏掉了什么吗?

以下代码有效(所有值都被填充),但不可排序:

Number::make('Months Remaining', function () { 
    return $this->foo('timeRemainingInMonths');
})
    ->sortable()
    ->onlyOnIndex();

以下代码有效(所有值都被填充),但不可排序:

Number::make('Months Remaining', function () { 
    return $this->foo('timeRemainingInMonths');
})
    ->sortable(function ($query, $direction) {
        $query->orderBy('timeRemainingInMonths', $direction);
    })
    ->onlyOnIndex();

以下代码会引发警告,提示“sortable”的第一个参数应为布尔类型,但实际传递的是字符串,但仍然导致所有值都被填充,但不可排序:

Number::make('Months Remaining', function () { 
    return $this->foo('timeRemainingInMonths');
}) 
    ->sortable('timeRemainingInMonths')
    ->onlyOnIndex();

上述三次尝试的结果:

在Laravel Nova中,是否有一种方法可以允许对由函数调用填充的列进行排序?

以下代码可排序但不填充任何值:

Number::make('Months Remaining', 'timeRemainingInMonths')
    ->sortable()
    ->onlyOnIndex();

上述尝试的结果:

在Laravel Nova中,是否有一种方法可以允许对由函数调用填充的列进行排序?

此帖子中的foo函数已重命名,但以下是该函数的内容:

private function foo($field)
{
    $lotNo = $this->lotNo()->first()->lot_no;
    foreach (self::$bar as $mixtureLot) {
        if ($mixtureLot['lotNo'] == $lotNo) {
            return $mixtureLot[$field];
        }
    }
    return 'N/A';
}

bar变量将始终是从API调用中填充的数组。如果它具有数据,数组中的每个项目将采用以下形式:

[
    'lotNo' => <字符串>,
    'qtyRemaining' => <整数>,
    'binIds' => <字符串数组>,
    'manufactureDate' => <字符串>,
    'expirationDate' => <字符串>,
    'timeRemainingInDays' => <整数>,
    'timeRemainingInMonths' => <整数>,
];
英文:

I am trying to allow a populated column in a Nova Lens to be sortable. The root data that populates my Number field comes from a function called during lens initialization to reach out to an API.

For some reason, I can either populate or sort the column values, but not both. Any idea what I am missing?

This code works (all values are populated) but is not sortable:

Number::make(&#39;Months Remaining&#39;, function () { 
    return $this-&gt;foo(&#39;timeRemainingInMonths&#39;);
})
    -&gt;sortable()
    -&gt;onlyOnIndex(),

This code works (all values are populated) but is not sortable:

Number::make(&#39;Months Remaining&#39;, function () { 
    return $this-&gt;foo(&#39;timeRemainingInMonths&#39;);
})
    -&gt;sortable(function ($query, $direction) {
        $query-&gt;orderBy(
&#39;timeRemainingInMonths&#39;, $direction);
    })
    -&gt;onlyOnIndex(),

This code throws an warning, saying Argument 1 passed to sortable is expected to be type bool, string given, but then still results in all values being populated, but is not sortable:

Number::make(&#39;Months Remaining&#39;, function () { 
    return $this-&gt;foo(&#39;timeRemainingInMonths&#39;);
}) 
    -&gt;sortable(&#39;timeRemainingInMonths&#39;)
    -&gt;onlyOnIndex();

Result of the above three attempts:

在Laravel Nova中,是否有一种方法可以允许对由函数调用填充的列进行排序?

This code is sortable but populates no values:

Number::make(&#39;Months Remaining&#39;, &#39;timeRemainingInMonths&#39;)
    -&gt;sortable()
    -&gt;onlyOnIndex(), 

Result of the above one attempt:
在Laravel Nova中,是否有一种方法可以允许对由函数调用填充的列进行排序?

The foo function has been renamed in this post, but here is the content of that function:

private function foo($field)
{
    $lotNo = $this-&gt;lotNo()-&gt;first()-&gt;lot_no;
    foreach (self::$bar as $mixtureLot) {
        if ($mixtureLot[&#39;lotNo&#39;] == $lotNo) {
            return $mixtureLot[$field];
        }
    }
    return &#39;N/A&#39;;
}

The bar variable will always be an array populated from an API call. If it has data, each item in the array will be in the form

[
    &#39;lotNo&#39; =&gt; &lt;string&gt;,
    &#39;qtyRemaining&#39; =&gt; &lt;integer&gt;,
    &#39;binIds&#39; =&gt; &lt;array of strings&gt;,
    &#39;manufactureDate&#39; =&gt; &lt;string&gt;,
    &#39;expirationDate&#39; =&gt; &lt;string&gt;, 
    &#39;timeRemainingInDays&#39; =&gt; &lt;integer&gt;,
    &#39;timeRemainingInMonths&#39; =&gt; &lt;integer&gt;,
];

答案1

得分: 1

根据文档再次阅读,对于计算字段(当您将数据作为第二个参数传递给字段时),有以下文本:

"由于它们与数据库列无关,计算字段可能无法进行排序。"

链接

英文:

So, reading the documentation again, there is this text for computed fields (when you pass data to the field as a second argument):

> Since they are not associated with a database column, computed fields may not be sortable

https://nova.laravel.com/docs/4.0/resources/fields.html#computed-fields

答案2

得分: 0

你可以通过重写 Model::newEloquentBuilder() 方法并重写构建器的 Builder::orderBy() 方法来添加自定义查询构建器到你的模型:

public function orderBy($column, $direction = 'asc'): static
{
    if($column === 'your-computed-field')
    {
        // 你的逻辑
    }
    else
    {
        parent::orderBy($column, $direction);
    }

    return $this;
}
英文:

You can add a custom query builder to your model overriding the Model::newEloquentBuilder() method and then overriding the Builder::orderBy() method of the builder:

public function orderBy($column, $direction = &#39;asc&#39;): static
{
    if($column === &#39;your-computed-field&#39;)
    {
        // your logic
    }
    else
    {
        parent::orderBy($column, $direction);
    }

    return $this;
}

huangapple
  • 本文由 发表于 2023年3月7日 09:53:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定