我有一个角度js应用程序,它使用带有这样的指令的ng-repeat:
<div data-ng-repeat="n in items">
<div data-my-directive
item="n"></div>
</div>
其中items
是一个带整数的数组。
根据用户的操作,items
数组可以完全销毁,并使用新的整数重新生成。
第一次,可能是[1,2,4,9] 接下来可能是[1,3,6,7] 例如。这取决于一些用户选择。
指令my-directive
将在服务器端执行一些业务逻辑,因此它会在加载后立即调用服务器。然后在结果返回后,它向用户显示一个很好的表。
问题是有些用户不会等到一切都很好并加载并切换视图(这意味着数组会发生变化)。在这种情况下,我看到对服务器的调用仍在执行,并且结果函数仍然被调用,即使指令本身已被销毁,因为ngRepeat已经反弹并且所有指令都被重新制作。
例如:
$http.get(service.url + '/filters').success(function(result) {
alert(result);
});
这将显示所有警报,甚至是不再显示在页面上的指令。 这带来了一些问题。我可以在数组更改时删除重复中的指令或类似的东西,以确保在不再存在的指令中不执行任何逻辑(或者不再在页面上显示)? 或者您对如何最好地解决这个问题有其他想法?
理想情况下,指令应该在ng-repeat自身反弹后消失,因此一旦数据从服务器返回,就不会执行任何逻辑。
答案 0 :(得分:1)
当用户更改参数时,您可以取消正在运行的请求并开始新的请求。
In this Scott Allen's blog post你可以找到有关这项工作的详细解释。
您开始使用您将调用的方法创建服务或工厂:
var getData = function(){
var canceller = $q.defer();
var cancel = function(reason){
canceller.resolve(reason);
};
var promise =
$http.get(service.url + '/filters', { timeout: canceller.promise})
.then(function(response){
return response.data;
});
return {
promise: promise,
cancel: cancel
};
};
然后你这样称呼它:
var request = service.getData();
$scope.requests.push(request);
request.promise.then(function(movie){
$scope.movies.push(movie);
clearRequest(request);
}, function(reason){
console.log(reason);
});
然后提供一个取消请求的方法:
$scope.cancel = function(){
var request = // retrieve the correct request from the requests array
request.cancel("User cancelled");
// Remove the request from the array
};
答案 1 :(得分:0)
所以我对你的问题有一些想法。
首先你可以使用ng-cloak,它可以防止浏览器在你的应用程序加载时以原始(未编译)形式短暂显示Angular html模板。如果我希望用户等到所有数据都返回到查看页面,我发现这非常有用。离。
<div id="template1" ng-cloak>{{ 'hello' }}</div>
第二次你可以尝试解决问题。解析包含一个或多个必须在路由更改之前成功解析的promise。这意味着您可以在实际更改路径之前等待数据可用。
$routeProvider
.when("/news", {
templateUrl: "newsView.html",
controller: "newsController",
resolve: {
message: function(messageService){
return messageService.getMessage();
}
}
})
答案 2 :(得分:0)
该指令需要使用$destroy
事件来取消正在进行的操作。
app.directive("myDirective", function() {
return {
controller: function($scope, $http, $q) {
var canceller = $q.defer();
var cancel = function(reason){
canceller.resolve(reason);
};
$http.get(url, { timeout: canceller.promise})
.then(function(response){
$scope.data = response.data;
});
$scope.$on('$destroy', function () {
cancel("Scope destroyed");
});
}
}
});
当ng-repeat
删除某个项目时,它会破坏该项目的范围。使用$destroy
事件取消正在进行的异步操作。
来自文档:
$destroy()
方法通常由ngRepeat
等指令用于管理循环的展开。在销毁范围之前,会在此范围内广播
$destroy
个事件。应用程序代码可以注册一个$destroy
事件处理程序,使其有机会执行任何必要的清理。