我对 Angular 很陌生,并试图实现一些“基本”的东西。我已经在谷歌上搜索了 2 天但没有成功,希望能得到一些帮助。
我有一个 html 页面,我正在尝试:
- 使用 HTTP POST 请求初始化数据
- 当用作过滤器的元素发生更改(即类别、按 asc/desc 排序...)时,通过 ng-change 事件调用函数以使用另一个 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 is called when model changed in programmatically