【问题标题】:Laravel collection always returns an object instead of an arrayLaravel 集合总是返回一个对象而不是一个数组
【发布时间】:2019-05-18 01:45:24
【问题描述】:

我有一个由 Vue 和 Vue Isotope 加载的新闻页面。 Vue isotope 要求我的数据是一个数组,以便当用户单击“加载更多”按钮时,我可以将更多文章附加到同位素。它的工作方式是,当用户单击“加载更多”时,使用 Laravel 的分页功能,我可以简单地将下一个加载的文章附加到我的 Vue 实例中现有的文章数组中。

我遇到的问题是我的 Laravel 集合总是返回一个对象而不是一个数组,即使我使用 toArray()

如果我使用 get() 直接从 eloquent 加载我的文章,这可以正常工作并且是一个数组,但是因为我需要将多个 eloquent 查询合并在一起,我不得不使用一个集合和merge() 来合并 4 个 eloquent查询到一个大集合。这就是我认为强制集合始终作为对象返回的原因。

以下是我的控制器功能:

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 的末尾,但是这会删除下一页的分页链接,并且只检索实际的帖子,所以我不能使用它。

这是一个小 sn-p,用于将初始 $allPosts 数据检索到 Vue 中

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

这里是当用户点击“加载更多”按钮时调用什么方法的 sn-p

        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 数据对象的 sn-p

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

            ],
            paginatedList: [

            ],
},

我的列表对象的图像(其中列表应该是一个数组):

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

【问题讨论】:

  • 你能分享一下list内容的sn-p吗?
  • 试试$allPosts->toArray()
  • @adam 这个我试过了,没区别。
  • @BoussadjraBrahim 已编辑帖子以附加图片。如您所见,列表是一个对象,但它必须是一个数组。不过需要注意的是,list 中的项目可以作为对象,但是 list 本身需要是一个数组。
  • list 是一个对象,因为您有一个 list 的键。删除 list 作为键,您将拥有一个基于 0 的索引数组。

标签: php laravel laravel-5 vue.js


【解决方案1】:

也遇到了这个问题,正如@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);

【讨论】:

    【解决方案2】:

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

    $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) 之类的东西可能会起作用。

    【讨论】:

    • 这几乎解决了这个问题。第一页很好,data 作为数组返回,但是第二页 data 仍然作为对象返回。
    • 您是否在您的收藏中使用宏或其他东西来实现paginate() 方法?你能发布那个代码吗?
    猜你喜欢
    • 2016-06-21
    • 2015-09-05
    • 2018-12-07
    • 1970-01-01
    • 2019-06-05
    • 2013-08-04
    • 2019-11-09
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多