设置美元范围.带有ng-change的myModel元素进入无限循环



我对Angular很陌生,想要实现一些"基本"的东西。我已经在谷歌上搜索了2天没有成功,希望你能帮助我。

我有一个html页面,我想:

  1. 用HTTP POST请求初始化数据
  2. 通过ng-change事件调用一个函数,当用作过滤器的元素被更改时(即类别,排序asc/desc…),用另一个HTTP POST更新数据

我的问题是,当我用HTTP响应(仅在这种情况下)以编程方式更新模型时,它触发附加到元素的ng-change事件,该元素本身调用更新函数,然后进入无限循环: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您能告诉我如何在不引发ng-change事件的情况下更新表单元素吗?

感谢

请注意,我不想使用$watch这样的解决方案:当模型以编程方式更改时,调用ngChange

您应该尝试在http://jsfiddle.net/或类似的地方添加一个工作示例。

我认为在猜测和没有测试,你需要保持最后的搜索,只有运行更新AJAX请求,如果它改变,因为它得到一个新的地址(或任何在JS中称为)每次-即使它的相同的值和重新评估再次

$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');
        });
    }
};

最新更新