如何将Array从Server复制到现有的Array引用

时间:2017-08-21 22:45:09

标签: javascript angularjs arrays

我一直在尝试使用角度js编写搜索引擎,但我无法将一个数组复制到另一个数组。当我启动代码时(在q.all然后函数中的service.FoundItems中),新数组(foundArray)显示为空数组。我搜索了如何将一个数组复制到另一个数组并尝试使用该方法,但它无法正常工作。请帮忙,这是代码,谢谢。

P.S。如果你需要HTML请告诉我。

(function () {
    'use strict';

    angular.module('narrowDownMenuApp', [])
        .controller('narrowItDownController', narrowItDownController)
        .service('MenuSearchService', MenuSearchService)
        .directive('searchResult', searchResultDirective);

    function searchResultDirective() {
        var ddo = {
            templateUrl: 'searchResult.html',
            scope: {
                items: '<'
            },
        };

        return ddo
    }

    narrowItDownController.$inject = ['MenuSearchService'];
    function narrowItDownController(MenuSearchService) {
        var menu = this;
        menu.input = "";
        menu.displayResult = [];
        menu.searchX = function(name) {
            menu.displayResult = MenuSearchService.FoundItems(menu.input, name);
            console.log(menu.displayResult);
        };
    }
    MenuSearchService.$inject = ['$http', '$q'];
    function MenuSearchService($http, $q) {
        var service = this;
        service.getMatchedMenuItems = function(name, searchTerm) {
            var deferred = $q.defer();
            var foundItems = [];
            var result =  $http({
                method: "GET",
                url: ('https://davids-restaurant.herokuapp.com/menu_items.json'),
                params: {
                    category: name
                }
            }).then(function (result) {
                var items = result.data;
                for (var i = 0; i < items.menu_items.length; i++) {
                    if (searchTerm === ""){
                        deferred.reject("Please enter search term");
                        i = items.menu_items.length;
                    }
                    else if (items.menu_items[i].name.toLowerCase().indexOf(searchTerm.toLowerCase()) ==! -1){
                        foundItems.push(items.menu_items[i].name)
                        deferred.resolve(foundItems);
                    }else {
                        console.log("doesn't match search");
                    }
                }
            });

            return deferred.promise;
        };
        service.FoundItems = function (searchTerm, name) {
            var searchResult = service.getMatchedMenuItems(name, searchTerm);
            var foundArray = [];
            $q.all([searchResult])
                .then(function (foundItems) {
                    foundArray = foundItems[0].slice(0);
                    foundArray.reverse();
                })
                .catch(function (errorResponse) {
                    foundArray.push(errorResponse);
                });
            console.log(foundArray);
            return foundArray;
        };
    };
})();

3 个答案:

答案 0 :(得分:1)

提图斯是对的。该函数始终立即返回foundArray的初始值,该值是一个空数组。承诺以异步方式执行,因此当您尝试更改foundArray时,为时已晚。您需要返回promise本身,然后使用.then()来检索值,就像您当前在方法中执行的那样。

答案 1 :(得分:1)

如果service.FoundItems函数的目标是返回对稍后使用服务器结果填充的数组的引用,请使用angular.copy将新数组从服务器复制到现有数组:

service.FoundItems = function (searchTerm, name) {
    var foundArray = [];
    var searchPromise = service.getMatchedMenuItems(name, searchTerm);
    foundArray.$promise = searchPromise
      .then(function (foundItems) {
        angular.copy(foundItems, foundArray);
        foundArray.reverse();
        return foundArray;
    })
      .catch(function (errorResponse) {
        return $q.reject(errorResponse);
    })
      .finally(function() {
        console.log(foundArray);
    });
    return foundArray;
}; 

我建议将promise作为名为$promise的属性附加到数组引用,以便它可以用于依赖于服务器结果的chain函数。

坦率地说,我不建议设计返回后来填充结果的数组引用的服务。如果你坚持以这种方式进行设计,那么就是这样做的。

  

我尝试了你推荐的$promise这件事。我想知道你将如何从它获得值,即数组。

在控制器中,使用.then的{​​{1}}方法查看数组的最终值:

$promise

要查看最终结果,需要在承诺的narrowItDownController.$inject = ['MenuSearchService']; function narrowItDownController(MenuSearchService) { var menu = this; menu.input = ""; menu.displayResult = []; menu.searchX = function(name) { menu.displayResult = MenuSearchService.FoundItems(menu.input, name); ̶c̶o̶n̶s̶o̶l̶e̶.̶l̶o̶g̶(̶m̶e̶n̶u̶.̶d̶i̶s̶p̶l̶a̶y̶R̶e̶s̶u̶l̶t̶)̶;̶ menu.displayResult.$promise .then(function(foundArray) { console.log(foundArray); console.log(menu.displayResult); }).catch(function(errorResponse) { console.log("ERROR"); console.log(errorResponse); }); }; } 块内移动console.log

答案 2 :(得分:0)

从快速查看代码开始,我认为你在那里遇到了一个简单的错误。你确定要吗

foundArray = foundItems[0].slice(0);

而不是

foundArray = foundItems.slice(0);