简体   繁体   中英

AngularJS custom filter called twice and delete input data on second call

Here are the codes.

var app = angular.module("nameApp", ["ngRoute"]);

app.controller("ctrlname", function ($scope, $http, $filter, apiKey, apiUrl) {
    $scope.data = {};
    $scope.currentPage = 1;
    $scope.pageSize = 5;
});

The $scope.data will contain an array of data from an HTTP GET request. The following is a code for a custom filter for the purpose of pagination of results. Basically, this will limit the results to only 5. Buttons for pagination will update $scope.currentPage's value.

app.filter("limitResults", function ($filter, $log) {
    return function (data, page, size) {
        if (angular.isArray(data) & angular.isNumber(page) && angular.isNumber(size)) {
            var startPage = (page - 1) * size;
            if (data.length < startPage) {
                return [];
            } else {
                $log.info(data);
                $log.info(page);
                $log.info(size);
                $log.info(startPage);
                return $filter("limitTo")(data.splice(startPage), size);
            }
        } else {
            return data;
        }
    }
});

This is the HTML page that will render the data.

<div class="row resultItems" ng-repeat="video in data.videos | limitResults:currentPage:pageSize">
    <div class="col-sm-3 testing">
        <img ng-src="{{video.snippet.thumbnails.default.url}}">
    </div>
    <div class="col-sm-9 testing">
        <h5>
            {{video.snippet.title}}
        </h5>
        <p>
            {{video.snippet.channelTitle}}
        </p>
        <p>
            {{video.snippet.description}}
        </p>
    </div>
</div>

I put a few lines of $log.info code in the custom filter in order to see what really happens when the filter is applied. The filter runs twice, which is a normal behaviour.

What I find confusing is that when the custom filter runs for the first time, $log.info(data) logs the original data received from a HTTP GET call to the console. However, when the custom filter runs for the second time, $log.info(data) logs an empty array to the console.

Given the fact that "$log.info(data); $log.info(page); $log.info(size);" get logged to the console, it is obvious that the second IF statement (if (data.length < startPage)) is evaluated to TRUE and the filter (return $filter("limitTo")(data.splice(startPage), size);) is applied.

I just don't understand why the array, which is the data passed to the custom filter, gets emptied when the filter runs the second time.

The reason you are seeing empty array is because of the splice method.

$filter("limitTo")(data.splice(startPage), size);

Splice method syntax

array.splice(start, deleteCount[, item1[, item2[, ...]]])

If splice method is called without second parameter, that means if deleteCount is not passed, deleteCount will be treated as [arr.length - start]. In your case, when the first time filter executes, the entire array becomes empty.

See this doc for splice method

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM