我正在创建一个ajax搜索页面,其中包含一个搜索输入框,一系列过滤器下拉菜单,然后是一个显示结果的UL。
由于搜索的过滤器部分将位于页面上的一个单独位置,我认为创建一个处理协调输入和ajax请求到搜索服务器端的服务是个好主意。然后可以通过几个单独的控制器调用它们(一个用于搜索框和结果,一个用于过滤器)。
我正在努力解决的主要问题是在调用ajax时刷新结果。如果我将ajax直接放在SearchCtrl控制器中,它可以正常工作,但当我将ajax移动到一个服务时,它会在调用服务上的find方法时停止更新结果。
我确信这是我错过的一些简单的东西,但我似乎无法看到它。
标记:
<div ng-app="jobs">
<div data-ng-controller="SearchCtrl">
<div class="search">
<h2>Search</h2>
<div class="box"><input type="text" id="search" maxlength="75" data-ng-model="search_term" data-ng-change="doSearch()" placeholder="Type to start your search..." /></div>
</div>
<div class="search-summary">
<p><span class="field">You searched for:</span> {{ search_term }}</p>
</div>
<div class="results">
<ul>
<li data-ng-repeat="item in searchService.results">
<h3>{{ item.title }}</h3>
</li>
</ul>
</div>
</div>
</div>
AngularJS:
var app = angular.module('jobs', []);
app.factory('searchService', function($http) {
var results = [];
function find(term) {
$http.get('/json/search').success(function(data) {
results = data.results;
});
}
//public API
return {
results: results,
find: find
};
});
app.controller("SearchCtrl", ['$scope', '$http', 'searchService', function($scope, $http, searchService) {
$scope.search_term = '';
$scope.searchService = searchService;
$scope.doSearch = function(){
$scope.searchService.find($scope.search_term);
};
$scope.searchService.find();
}]);
这是一个粗略的JSFiddle,我已经注释掉了ajax,我只是手动更新结果变量作为示例。为简洁起见,我没有包含过滤器下拉列表。
我对AngularJS很新,所以如果我以完全错误的方式处理它,请告诉我:)
答案 0 :(得分:29)
在HTML中,您需要引用控制器$ scope上定义的属性。一种方法是在控制器中将$scope.searchService.results
绑定到searchService.results
:
$scope.searchService.results = searchService.results;
现在这一行将起作用:
<li data-ng-repeat="item in searchService.results">
在您的服务中,使用angular.copy()
而不是为results
分配新的数组引用,否则您的控制器的$ scope将失去其数据绑定:
var new_results = [{ 'title': 'title 3' },
{ 'title': 'title 4' }];
angular.copy(new_results, results);
Fiddle。在小提琴中,我注释掉了对find()的初始调用,因此您可以在搜索框中输入内容时看到更新。
答案 1 :(得分:1)
问题是您永远不会在您的范围内更新结果。有很多方法可以做到这一点,但根据您当前的代码,您可以先修改查找函数以返回结果:
function find(term) {
$http.get('/json/search').success(function(data) {
var results = data.results;
});
//also notice that you're not using the variable 'term'
//to perform a query in your webservice
return results;
}
您在“公开API”中使用了模块模式,因此 searchService 会返回查找函数和结果数组,但是你想让找到这个函数成为负责实际返回结果的。
除此之外,无论何时在您的范围内调用 doSearch(),您都希望更新 searchService
返回的结果的当前结果$scope.doSearch = function(){
$scope.searchService.results = searchService.find($scope.search_term);
};
我用我的想法更新了你的jsfiddle,不起作用,但我添加了一些提交和日志来帮助你调试这个问题。 http://jsfiddle.net/XTQSu/3/