我一直在尝试使用角度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;
};
};
})();
答案 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);