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

前端之家收集整理的这篇文章主要介绍了使用AngularJS中的oboe.js流式传输JSON的解决方案?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我对Angular很新,所以也许我会问不可能,但无论如何,这是我的挑战.

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

我发现oboe.js用于解析JSON流并使用bower将其添加到我的项目中. (凉亭安装双簧管 – 保存).

我想在流式传输期间更新控制器模型.我没有使用$q实现的pomises,因为只有一个.resolve(…)可能,我希望通过流加载多页数据,因此需要在每个页面调用$digest.调用的restful服务是/ service / tasks / search

我创建了一个带有搜索功能的工厂,我在控制器中调用它:

'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();
                        });
            }
        };
    });

我的控制器:

'use strict';
angular.module('myStreamingApp')
    .controller('MyCtrl',function($scope,Stream) {
         $scope.data = [];
         Stream.search('tasks',$scope);
     });

这一切都有效.一段时间后,系统变慢,刷新浏览器后http调用不会终止.当加载的记录太多时,浏览器(chrome)也会崩溃.
也许我在错误的轨道上,因为将范围传递给工厂搜索功能并没有“感觉”正确,我怀疑在该范围内调用$digest会给我带来麻烦.欢迎提出有关此主题的任何想法.特别是如果您有实现它的想法,工厂(或服务)可以返回承诺,我可以使用

$scope.data = Stream.search('tasks');

在控制器中.

我进一步深入研究并提出了以下解决方案.它可能会帮助某人:

工厂(名为Stream)有一个搜索功能,它传递Ajax请求的参数和回调函数.正在为流加载的每个数据页调用回调.回调函数通过deferred.promise调用,因此范围可以自动更新每个页面.为了访问搜索功能,我使用一个服务(名为Search),该服务最初返回一个空的数据.随着流的进行,工厂调用服务传递的回调函数,并将页面添加到数据中.

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

服务和工厂:

'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;
                }
            };
        });

现在我可以在控制器内调用服务,并将服务的响应分配给范围:

$scope.mydata = Search({schema: 'tasks'});

2014年8月30日更新

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

猜你在找的Angularjs相关文章