首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用oboe.js在AngularJS中传输JSON的解决方案?

使用oboe.js在AngularJS中传输JSON的解决方案?
EN

Stack Overflow用户
提问于 2014-08-29 11:59:19
回答 1查看 5.6K关注 0票数 8

我对角度很陌生,所以也许我是在问不可能的问题,但无论如何,这是我的挑战。

由于我们的服务器无法对JSON数据进行分页,所以我希望流JSON并将其逐页添加到控制器的模型中。用户不必等待整个流加载,所以我刷新每个X (pagesize)记录的视图。

我找到了解析JSON流的oboe.js,并使用bower将其添加到我的项目中。(鲍尔安装双簧管-保存)。

我想在流过程中更新控制器模型。我没有使用$q实现,因为只有一个.resolve(.)可能的话,我希望通过流加载多个页面的数据,所以每个页面都需要调用$digest。调用的restful服务是/ service /任务/搜索

我创建了一个带有搜索函数的工厂,我在控制器中调用了该函数:

代码语言:javascript
复制
'use strict';

angular.module('myStreamingApp')
    .factory('Stream', function() {
        return {
            search: function(schema, scope) {
                var loaded = 0;
                var pagesize = 100;
                // JSON streaming parser oboe.js
                oboe({
                    url: '/service/' + schema + '/search'
                })
                        // process every node which has a schema
                        .node('{schema}', function(rec) {
                            // push the record to the model data
                            scope.data.push(rec);
                            loaded++;
                            // if there is another page received then refresh the view
                            if (loaded % pagesize === 0) {
                                scope.$digest();
                            }
                        })
                        .fail(function(err) {
                            console.log('streaming error' + err.thrown ? (err.thrown.message):'');
                        })
                        .done(function() {
                            scope.$digest();
                        });
            }
        };
    });

我的控制器:

代码语言:javascript
复制
'use strict';
angular.module('myStreamingApp')
    .controller('MyCtrl', function($scope, Stream) {
         $scope.data = [];
         Stream.search('tasks', $scope);
     });

所有的缝都要起作用。但是,过了一段时间,系统会变慢,并且在刷新浏览器之后,http调用不会终止。此外,浏览器(chrome)崩溃时,有太多的记录加载。也许我走错了路,因为把范围传递给工厂搜索函数并不“感觉”正确,我怀疑在这个范围上调用$digest会给我带来麻烦。任何关于这个问题的想法都是受欢迎的。尤其是如果您有一个实现它的想法,工厂(或服务)可以返回一个承诺,而我可以使用。

代码语言:javascript
复制
$scope.data = Stream.search('tasks');

在控制器里。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-30 11:54:54

我进一步研究了一下,并想出了以下解决方案。它可能对某人有帮助:

工厂(名为Stream)有一个搜索函数,它为Ajax请求传递参数,还有一个回调函数。对流加载的每一页数据都调用回调。回调函数是通过deferred.promise调用的,因此可以通过每个页面自动更新作用域。为了访问搜索函数,我使用了一个服务(名为Search),它最初返回一个空的数据数组。随着流的发展,工厂调用服务传递的回调函数,页面被添加到数据中。

现在,我可以在控制器中调用搜索服务表单,并将返回值分配给作用域数据数组。

服务和工厂:

代码语言:javascript
复制
'use strict';
angular.module('myStreamingApp')
        .service('Search', function(Stream) {
            return function(params) {
                // initialize the data
                var data = [];
                // add the data page by page using a stream
                Stream.search(params, function(page) {
                    // a page of records is received.
                    // add each record to the data
                    _.each(page, function(record) {
                        data.push(record);
                    });
                });
                return data;
            };
        })
        .factory('Stream', function($q) {
            return {
                // the search function calls the oboe module to get the JSON data in a stream
                search: function(params, callback) {
                    // the defer will be resolved immediately
                    var defer = $q.defer();
                    var promise = defer.promise;
                    // counter for the received records
                    var counter = 0;
                    // I use an arbitrary page size.
                    var pagesize = 100;
                    // initialize the page of records
                    var page = [];
                    // call the oboe unction to start the stream
                    oboe({
                        url: '/api/' + params.schema + '/search',
                        method: 'GET'
                    })
                            // once the stream starts we can resolve the defer.
                            .start(function() {
                                defer.resolve();
                            })
                            // for every node containing an _id
                            .node('{_id}', function(node) {
                                //  we push the node to the page
                                page.push(node);
                                counter++;
                                // if the pagesize is reached return the page using the promise
                                if (counter % pagesize === 0) {
                                    promise.then(callback(page));
                                    // initialize the page
                                    page = [];
                                }
                            })
                            .done(function() {
                                // when the stream is done make surethe last page of nodes is returned
                                promise.then(callback(page));
                            });
                    return promise;
                }
            };
        });

现在,我可以从控制器中调用服务,并将服务的响应分配给作用域:

代码语言:javascript
复制
$scope.mydata = Search({schema: 'tasks'});

2014年8月30日更新

我已经创建了一个角双簧管模块,上面的解决方案有点结构。https://github.com/RonB/angular-oboe

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25567864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档