11

検索入力ボックス、一連のフィルター ドロップダウン、および結果が表示される UL で構成される ajax 検索ページを作成しています。

検索のフィルター部分はページの別の場所にあるため、検索サーバー側への入力と ajax 要求の調整を処理するサービスを作成することをお勧めします。これは、いくつかの別個のコントローラー (検索ボックスと結果用に 1 つ、フィルター用に 1 つ) によって呼び出すことができます。

私が苦労している主なことは、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に非常に慣れていないので、まったく間違った方法で行っている場合は、そのことを教えてください:)

4

2 に答える 2

29

HTML では、コントローラーの $scope で定義されたプロパティを参照する必要があります。これを行う 1 つの方法は、コントローラーで一度バインドすることです$scope.searchService.resultssearchService.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);

フィドル。フィドルでは、find() の最初の呼び出しをコメントアウトしたので、検索ボックスに何かを入力すると更新が行われることがわかります。

于 2013-03-11T18:22:41.253 に答える
1

問題は、スコープ内で結果を更新していないことです。これを行うには多くの方法がありますが、現在のコードに基づいて、最初に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()を呼び出すたびに、 searchServiceによって返された結果の現在の結果を更新する必要があります。

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

jsfiddle を私のアイデアで更新しましたが、機能していませんが、この問題のデバッグに役立つコメントとログを追加しました。http://jsfiddle.net/XTQSu/3/

于 2013-03-11T16:22:47.560 に答える