0

私はAngularにかなり慣れていないので、「基本的な」何かを達成しようとしています。私は成功せずに2日間グーグルしてきましたが、助けていただければ幸いです。

私がしようとしているhtmlページがあります:

  1. HTTP POST リクエストでデータを初期化する
  2. フィルターとして使用される要素が変更されたときに、ng-change イベントを介して関数を呼び出して、別の HTTP POST でデータを更新します (つまり、カテゴリ、asc/desc の並べ替えなど)。

私の問題は、HTTP 応答(この場合のみ)を使用してプログラムでモデルを更新すると、要素に関連付けられた ng-change イベントがトリガーされ、それ自体が update 関数を呼び出してから無限ループに入るということです: ng -change -> 更新機能 -> ng-change -> 更新機能

注: Angular Material テンプレートを使用していますが、コードは変更されません

HTML

<html ng-app="MyApp">
    <body layout="column" ng-controller="SearchServiceController">
        <h1 class="md-headline">Filter results</h1>
        <form name="searchServiceForm" novalidate>
            <md-input-container>
                <md-select placeholder="Choose category" ng-model="searchService.selectedCategory" ng-change="changedSearchServiceCriteria()">
                    <md-option ng-value="category.value" ng-repeat="category in listOfCategories">{{ category.title }}</md-option>
                </md-select>
             </md-input-container>
             <md-input-container>
                 <md-select placeholder="Sort by" ng-model="searchService.sortBy" ng-change="changedSearchServiceCriteria()">
                     <md-option ng-value="criteria.value" ng-repeat="criteria in sortByCriterias">{{ criteria.title }}</md-option>
                  </md-select>
              </md-input-container>
          </form>
          <h1 class="md-headline">{{ selectedCategory.title }}</h1>
          <p class="md-body-1">{{ selectedCategory.description }}</p>
    </body>
</html>

JS

var app = angular.module('MyApp', ['ngMaterial']);

app.controller('SearchServiceController', function($scope, $http, $location) {
  // Initialize data using the category id parameter in the URL
  $http({
    method: 'POST',
    url: '/projets/get-offerings-list',
    data: {selectedCategory: $location.path().split("/")[4]},
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
      .success(function(response) {
        alert('INIT');
        $scope.listOfCategories = response.listOfCategories;
        $scope.sortByCriterias = response.sortByCriterias;
        $scope.searchService = response.searchService;
      })
      .error(function(response) {
        console.log('Failure occured');
      });

  // Update data
  $scope.changedSearchServiceCriteria = function() {
    $http({
    method: 'POST',
    url: '/projets/get-offerings-list',
    data: {selectedCategory: $location.path().split("/")[4]},
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
      .success(function(response) {
        alert('UPDATE');
        $scope.listOfCategories = response.listOfCategories;
        $scope.sortByCriterias = response.sortByCriterias;
        $scope.searchService = response.searchService;
      })
      .error(function(response) {
        console.log('Failure occured');
      });
  };
});

結果

INIT
Object {listOfCategories: Array[3], sortByCriterias: Array[2], searchService: Object}
UPDATE
Object {listOfCategories: Array[3], sortByCriterias: Array[2], searchService: Object}
UPDATE
Object {listOfCategories: Array[3], sortByCriterias: Array[2], searchService: Object}
UPDATE
Object {listOfCategories: Array[3], sortByCriterias: Array[2], searchService: Object}
UPDATE
Object {listOfCategories: Array[3], sortByCriterias: Array[2], searchService: Object}
UPDATE
Object {listOfCategories: Array[3], sortByCriterias: Array[2], searchService: Object}
....infinite loop....

これは、HTTP 要求の応答を使用せずにプログラムでモデルを更新している場合には発生しません。 ここを参照してください: http://plnkr.co/edit/baNjr85eAOkKVu4dnf1m?p=preview

ありがとう

そこのような $watch を使用した回避策を使用したくないことに注意してください:プログラムでモデルが変更されたときに ngChange が呼び出されます

4

1 に答える 1

0

実際の例をhttp://jsfiddle.net/などに追加してみてください。

私は推測で、最後の検索を保持し、毎回新しいアドレス(またはJSで呼び出されるもの)を取得するたびに変更された場合にのみ更新AJAXリクエストを実行する必要があることをテストしていないと思います-同じ値であってもそして再度再評価します

$scope.searchService = "";
$scope.lastSearch = ""

// Update data using form elements
$scope.changedSearch = function() {

    if($scope.searchService != $scope.lastSearch){

      $http({
        method: 'POST',
        url: '/projects/get-list',
        data: $scope.searchService,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
      })
        .success(function(response) {
            // Request succeeded? Display message
            console.log('UPDATE');
            console.log(response);
            // Update data
            $scope.listOfCategories = response.listOfCategories;
            $scope.sortByCriterias = response.sortByCriterias;
            $scope.searchForm = response.searchForm;
        })
          .error(function(response) {
            // Request failed? Display message
            console.log('Failure occured');
        })
          .complete(function(response) {
            // do after success or error
            $scope.lastSearch = $scope.searchService;
            console.log('complete');
        });
    }
};
于 2015-07-16T21:14:19.487 に答える