我有一个骨干应用程序,可以将API中的一些数据加载到图表中。此应用程序有几个选项卡,可以导航以访问这些不同的图表,每个选项卡执行一个路径。每个图表都是ChartView的一个实例,其中包含相应的数据。
我遇到一些可能需要一段时间的API调用问题。当请求花费太长时间时,一些用户开始快速循环通过选项卡,彼此之后快速执行每个路由。这会激活所有集合提取,最终会破坏界面,因为一些回调会进行一些渲染。
所以我的问题是,我怎样才能确保每次加载新路由时(即使是快速连续完成)所有待处理或已启动的请求都已停止,因此没有"请求成功&#34 ;回调被解雇了?
答案 0 :(得分:1)
我建议,覆盖Backbone.Views删除方法。使用常规stopListening,中止ajax调用,还设置类似this.removed=true
的标志。在渲染功能中检查已移除的标志,如果存在则不进行渲染。如果点击已经很快完成,您可能需要在拨打任何电话之前进行检查。
答案 1 :(得分:1)
根据Ravi Hamsa的回复,我实施了一个对象,该对象被注入到每个路径中以保存请求以及路由是否仍然相关。
看起来像这样:
var RouteContext = function RouteContext() {
this._xhrs = {};
this.stopped = false;
this.manageRequest = function(xhr) {
this.xhrs.push(xhr);
}
this.stop = function() {
this.stopped = true;
_.invoke(this.xhrs, 'abort');
}
}
我重写了Backbone.Router路由方法,如下所示:
route: function(route, name, callbackFactory) {
var callback;
if (_.isFunction(callbackFactory)) {
var context = new RouteContext();
callback = callbackFactory(context);
// When a new route is opened, this route should be stopped and all
// corresponding jqXHR's should be aborted.
App.mediator.on('tabClicked', function() {
context.stop();
});
} else {
callback = callbackFactory;
}
return Backbone.Router.prototype.route.call(this, route, name, callback);
}
我现在可以使用这样的上下文创建一个新的路由方法:
var routeFactory = function(routeContext) {
// Might do some route initialisation here.
return function() {
this.reset(routeContext);
// This function is the actual function that will be called when a route is triggered.
if (routeContext.stopped === false) {
myView.renderChart();
}
}
};
// Register the route on the router.
myRouter.route('route', 'name', routeFactory);
因为可以多次调用路由,所以当重新调用路由时,我将RouteContext重置为原始状态。
在我的路线中,我一直在检查我需要做什么,以便渲染routeContext.stopped是否仍为false。如果确实如此,我不进行渲染。