Ng-repeat与指令:如何销毁重复项目后,数组已经改变

ng-repeat with directive: how to destroy repeated items after array has changed?

本文关键字:数组 改变 项目 指令 何销毁 Ng-repeat      更新时间:2023-09-26

我有一个angular 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自身反弹后消失,因此数据从服务器返回后不会立即执行逻辑。

当用户更改参数时,可以取消正在运行的请求并重新启动一个。

在这篇Scott Allen的博客文章中,你可以找到这是如何工作的详细解释。

你开始用你将要调用的方法创建一个服务或工厂:

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

所以我对你的问题有一些想法。

第一个你可以使用ng-cloak,它用来防止Angular html模板在你的应用程序加载时以原始(未编译)的形式被浏览器短暂显示。如果我想让用户等到所有数据返回后才查看页面,我发现这非常有用。交货。

<div id="template1" ng-cloak>{{ 'hello' }}</div>

你可以尝试解析。一个解析包含一个或多个必须在路由改变之前成功解析的承诺。这意味着你可以等待数据变得可用,然后再实际更改路由。

$routeProvider
    .when("/news", {
        templateUrl: "newsView.html",
        controller: "newsController",
        resolve: {
            message: function(messageService){
                return messageService.getMessage();
        }
    }
})

指令需要使用$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事件取消正在进行的异步操作。

From the Docs:

$destroy()方法通常被指令(如ngRepeat)用于管理循环的展开。

在一个作用域被销毁之前,一个$destroy事件被广播到这个作用域。应用程序代码可以注册一个$destroy事件处理程序,这将使它有机会执行任何必要的清理。

——AngularJS rootScope美元。——$destroy