@H_
404_0@
我对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