我对角度很陌生,所以也许我是在问不可能的问题,但无论如何,这是我的挑战。
由于我们的服务器无法对JSON数据进行分页,所以我希望流JSON并将其逐页添加到控制器的模型中。用户不必等待整个流加载,所以我刷新每个X (pagesize)记录的视图。
我找到了解析JSON流的oboe.js,并使用bower将其添加到我的项目中。(鲍尔安装双簧管-保存)。
我想在流过程中更新控制器模型。我没有使用$q实现,因为只有一个.resolve(.)可能的话,我希望通过流加载多个页面的数据,所以每个页面都需要调用$digest。调用的restful服务是/ service /任务/搜索
我创建了一个带有搜索函数的工厂,我在控制器中调用了该函数:
'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');在控制器里。
发布于 2014-08-30 11:54:54
我进一步研究了一下,并想出了以下解决方案。它可能对某人有帮助:
工厂(名为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日更新
我已经创建了一个角双簧管模块,上面的解决方案有点结构。https://github.com/RonB/angular-oboe
https://stackoverflow.com/questions/25567864
复制相似问题