Подтвердить что ты не робот

AngularJS - использование сервиса как модели, ng-repeat не обновляет

Я создаю страницу поиска 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, и я просто обновляю переменную результатов вручную в качестве примера. Для краткости я не включил выпадающие списки фильтров.

http://jsfiddle.net/XTQSu/1/

Я очень новичок в AngularJS, поэтому, если я пойду об этом совершенно не так, скажите мне так:)

4b9b3361

Ответ 1

В вашем HTML вам нужно ссылаться на свойство, определенное в вашем пространстве $control. Один из способов сделать это - привязать $scope.searchService.results к searchService.results один раз в вашем контроллере:

$scope.searchService.results = searchService.results;

Теперь эта строка будет работать:

<li data-ng-repeat="item in searchService.results">

В вашей службе используйте angular.copy() вместо того, чтобы назначать новую ссылку на массив results, в противном случае область вашего контроллера $потеряет привязку данных:

var new_results = [{ 'title': 'title 3' }, 
                   { 'title': 'title 4' }];
angular.copy(new_results, results);

Fiddle. В скрипке я прокомментировал первоначальный вызов find(), поэтому вы можете увидеть, что обновление происходит, когда вы вводите что-то в поле поиска.

Ответ 2

Проблема заключается в том, что вы никогда не обновляете свои результаты в своей области. Существует много способов сделать это, но на основе вашего текущего кода вы можете сначала изменить функцию find, чтобы вернуть результаты:

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 возвращает функцию find и массив результатов, но вы хотите, чтобы функция find была ответственна за фактическое возвращение результатов.

Отметьте, что в любом случае, когда вы вызываете doSearch() в своей области, вам нужно обновить текущие результаты для тех, которые были возвращены вашей поисковой службой

$scope.doSearch = function(){
    $scope.searchService.results = searchService.find($scope.search_term);
};

Я обновил ваш jsfiddle своими идеями, не работает, но добавил некоторые коммиты и журналы, чтобы помочь вам отладить эту проблему. http://jsfiddle.net/XTQSu/3/