英文:
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();
上述三次尝试的结果:
以下代码可排序但不填充任何值:
Number::make('Months Remaining', 'timeRemainingInMonths')
->sortable()
->onlyOnIndex();
上述尝试的结果:
此帖子中的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('Months Remaining', function () {
return $this->foo('timeRemainingInMonths');
})
->sortable()
->onlyOnIndex(),
This code works (all values are populated) but is not sortable:
Number::make('Months Remaining', function () {
return $this->foo('timeRemainingInMonths');
})
->sortable(function ($query, $direction) {
$query->orderBy(
'timeRemainingInMonths', $direction);
})
->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('Months Remaining', function () {
return $this->foo('timeRemainingInMonths');
})
->sortable('timeRemainingInMonths')
->onlyOnIndex();
Result of the above three attempts:
This code is sortable but populates no values:
Number::make('Months Remaining', 'timeRemainingInMonths')
->sortable()
->onlyOnIndex(),
Result of the above one attempt:
The foo
function has been renamed in this post, but here is the content of that function:
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';
}
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
[
'lotNo' => <string>,
'qtyRemaining' => <integer>,
'binIds' => <array of strings>,
'manufactureDate' => <string>,
'expirationDate' => <string>,
'timeRemainingInDays' => <integer>,
'timeRemainingInMonths' => <integer>,
];
答案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 = 'asc'): static
{
if($column === 'your-computed-field')
{
// your logic
}
else
{
parent::orderBy($column, $direction);
}
return $this;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论