vue.js Laravel集合总是返回一个对象而不是数组

bbmckpt7  于 2023-04-07  发布在  Vue.js
关注(0)|答案(3)|浏览(168)

我有一个新闻页面,正在被Vue和Vue Isotope加载。Vue Isotope要求我的数据是一个数组,这样当用户点击“加载更多”按钮时,我可以将更多的文章添加到isotope中。其工作方式是,当用户点击“加载更多”时,使用Laravel的分页功能,我可以简单地将下一个加载的文章添加到Vue示例中现有的文章数组中。
我遇到的问题是,我的Laravel集合总是返回一个对象而不是一个数组,即使我使用toArray()
如果我使用get()直接从elongate加载我的文章,这很好,是一个数组,但是因为我需要合并多个elongate查询,我被迫使用一个集合和merge()将4个elongate查询合并到一个大集合中。我相信这就是强制集合总是作为对象返回的原因。
下面是我从控制器的功能:

public function apiIndex()
{
    $articles = Article::latest('featuredArticle')->latest()->published()->get();
    $twitterPosts = TwitterPost::where('published', 'published')->get();
    $facebookPosts = FacebookPost::where('published', 'published')->get();
    $vimeoPosts = VimeoPost::where('published', 'published')->get();

    $articles->map(function ($post) {
        $post['type'] = 'Article';
        return $post;
    });

    $twitterPosts->map(function ($post) {
        $post['type'] = 'Twitter';
        return $post;
    });

    $facebookPosts->map(function ($post) {
        $post['type'] = 'Facebook';
        return $post;
    });

    $vimeoPosts->map(function ($post) {
        $post['type'] = 'Vimeo';
        return $post;
    });

    $allPosts = collect();

    $allPosts = $allPosts->merge($articles);
    $allPosts = $allPosts->merge($twitterPosts);
    $allPosts = $allPosts->merge($facebookPosts);
    $allPosts = $allPosts->merge($vimeoPosts);

    $allPosts = $allPosts->sortByDesc('created_at')->paginate(15);

    return response()->json($allPosts);

}

最接近我已经能够得到的是通过添加->values()$allPosts的末尾,但这删除了下一页的分页链接,只检索实际的职位,所以我不能使用这个。
下面是一个小片段,用于将初始$allPosts数据检索到Vue中

mounted () {
        axios.get(this.page)
        .then(response => ([
            this.list = response.data.data,
            this.page = response.data.next_page_url
        ]))
    },

下面是用户单击“Loadmore”按钮时调用的方法的代码片段

loadMore: function() {
            axios.get(this.page)
            .then(response => ([
                this.paginatedList = response.data.data,
                this.list.push(this.list, this.paginatedList),
                this.page = response.data.next_page_url
            ]))
        },

因为响应是一个对象,所以使用this.list.push()不起作用并抛出错误,因为this.list应该是一个数组。
另外,这里是我的Vue数据对象的一个片段

data: {
            page: "{{route('api-news')}}",
            list: [ 

            ],
            paginatedList: [

            ],
},

我的list对象的图像(其中list应该是数组):

如何强制$allPosts作为数组返回?

ars1skjm

ars1skjm1#

我会尝试在paginate() * 之前添加对values()的调用,而不是在paginate()之后。

$allPosts = $allPosts->sortByDesc('created_at')->values()->paginate(15);
return response()->json($allPosts);

Vue判断一个数组是被当作数组还是对象的方法是通过查看键:如果它们是数字、零索引和顺序,则它将把它视为数组,否则,它将把它视为对象。
在你的例子中,sortByDesc()集合方法维护了原始的键,这样Vue就可以看到非顺序键并将其作为对象处理。通过values()运行你的排序集合,你应该得到一个正确索引的集合传递给Vue。

更新:

根据您的评论,上面的解决方案只对结果的第一页有效,而对其他页无效,我怀疑paginate()方法也在维护原始键。因此,第一个块的键从0开始,但第二个块的键从15开始。您可能需要覆盖它,以便每个块都重新索引为0。
你也可以在将结果推入模型之前在Vue代码中这样做,比如response.data.list.filter(item => item)

sh7euo9m

sh7euo9m2#

正如@Graeme所指出的,同样遇到了这个问题,这在第一页上有效,但在第二页上无效。最后,我手动覆盖了LengthAwarePaginator中的项并重置了数组索引。

$collect = $Products->get()->values();
        
        $ProductsPaginated = ProductResource::collection($collect)->paginate(12);
        $items = $ProductsPaginated->items();
        
        $decodeFix = json_decode($ProductsPaginated->toJson());
        $decodeFix->data = array_values($items);

        return json_encode($decodeFix);
mbyulnm0

mbyulnm03#

另一种方式:

$products = Product::where(...)->get()->paginate(25);
$products->setCollection($products->getCollection()->values());

相关问题