17.02.2015, 14:01
|
Интересующийся
|
|
Регистрация: 28.08.2011
Сообщений: 28
|
|
Как правильно изменять наблюдаемый объект?
Здравствуйте !
Есть большая форма, с зависимыми между собой элементами. При изменении значений формы, нужно слать запрос, для получения ответа от сервера.
<select ng-model="form.brandId" ng-options="brand.id as brand.name for brand in brands"></select>
<select ng-model="form.modelId" ng-options="model.id as model.name for model in models"></select>
$scope.form = {};
$scope.$watchCollection('form', function(form){
if ( ! form.brandId && form.modelId){
delete form.modelId;
}
console.log('load data ...');
});
И возникает проблема в самом $watch-ре, если нужно удалить значение модели, когда выбран бренд, то функция вызовется повторно, т.к. наблюдаемый объект изменился. И из-за этой ситуации, появляются лишние запросы к серверу.
Подскажите, пожалуйста, как работать с множеством зависимых элементов, чтобы не допускать повторных вызовов $watchCollection ?
|
|
17.02.2015, 14:59
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
capscom, ты бы примерчик тестовый нормально сделал для начала... К чему эти огрызки? Они что-то могут объяснить?
|
|
17.02.2015, 15:10
|
Интересующийся
|
|
Регистрация: 28.08.2011
Сообщений: 28
|
|
Сообщение от ksa
|
capscom, ты бы примерчик тестовый нормально сделал для начала... К чему эти огрызки? Они что-то могут объяснить?
|
Исправляюсь. Вот пример, на базе кода описанного в задаче. Пихать огромную форму с проекта, нет смысла, там очень много условий, помимо текущих.
plnkr
Собственно проблема видна при выполнении delete form.modelId. После чего функция запускается повторно, так как объект изменился. Вопрос как сделать так, чтобы можно было изменять в объекте разом несколько свойств и функция в $watchCollection отрабатывала разово.
Последний раз редактировалось capscom, 17.02.2015 в 16:14.
|
|
17.02.2015, 15:38
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от capscom
|
Пихать огромную форму с проекта, нет смысла
|
Она тут никому и не нужна...
Пример должен быть максимально прост и выложен прямо тут. Причем с возможностью запуска...
А твоя ссылка дает мне чистую страницу.
|
|
17.02.2015, 16:17
|
Интересующийся
|
|
Регистрация: 28.08.2011
Сообщений: 28
|
|
Сообщение от ksa
|
Она тут никому и не нужна...
Пример должен быть максимально прост и выложен прямо тут. Причем с возможностью запуска...
А твоя ссылка дает мне чистую страницу.
|
Странно, а так ?
jsfiddle
|
|
17.02.2015, 16:20
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от capscom
|
а так ?
|
Второй вариант рабочий...
Но я предлагаю таки тут показывать, так оно и не потеряется.
Вот примерчик, два селекта...
<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/1.1.4/angular.min.js"></script>
<!--
<script src='http://code.jquery.com/jquery-latest.js'></script>
<link rel='stylesheet type=text/css href=tmp.css' />
-->
<style type='text/css'>
</style>
<script type='text/javascript'>
function cntrl($scope) {
$scope.items1 = [
{name: 0},
{name: 1},
{name: 2},
{name: 3},
{name: 4}
];
$scope.items2 = [
{name: 0},
{name: 1},
{name: 2},
{name: 3},
{name: 4}
];
$scope.$watch(
"items1",
function(newVal, oldVal) {
// получили изменение
},
true
);
$scope.$watch(
"items2",
function(newVal, oldVal) {
// получили изменение
},
true
);
$scope.item1 = $scope.items1[1];
$scope.item2 = $scope.items2[2];
}
</script>
</head>
<body>
<div ng-controller="cntrl">
<select ng-model="item1" ng-options="o.name for o in items1"></select>
<select ng-model="item2" ng-options="o.name for o in items2"></select>
</div>
</body>
</html>
Что ты с ними хотел замутить?
|
|
17.02.2015, 16:32
|
Интересующийся
|
|
Регистрация: 28.08.2011
Сообщений: 28
|
|
Суть простая, если мы в первом селекте убираем значение, то автоматом сбрасывается значение в связанном селекте. Например, есть селекты: марка и модель авто, если юзер сбрасывает марку, то и значение модели не нужно.
В объекте form, хранятся все выбранные значения юзером. И при изменении свойства шлется запрос постом к серваку.
$scope.$watchCollection('form', function(form){
$scope.posts = PostService.getPosts(form);
});
Как-то не хочется вешать по $watch на каждый отдельный селект. У меня на форме порядка 30 элементов, и явно будет все подтупливать. Хотел как-то красиво обойтись одним. Да вот столкнулся с траблой, что если сбрасывать значения связанных селектов, непосредственно в функции $watchCollection, получаем кучу левых запросов.
|
|
17.02.2015, 16:50
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
Сообщение от capscom
|
если юзер сбрасывает марку, то и значение модели не нужно
|
Тогда зачем вообще это "слежение"?
Можно просто повесить обработчик на селект и все дела...
<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/1.1.4/angular.min.js"></script>
<!--
<script src='http://code.jquery.com/jquery-latest.js'></script>
<link rel='stylesheet type=text/css href=tmp.css' />
-->
<style type='text/css'>
</style>
<script type='text/javascript'>
function cntrl($scope) {
$scope.brands = [{id: null, name: 'B1'}, {id: 1, name: 'B2'}, {id: 2, name: 'B3'}];
$scope.models = [{id: 1, name: 'M1'}, {id: 2, name: 'M2'}];
$scope.brand = null;
$scope.model = null;
$scope.newBrand = function() {
if ($scope.brand==null) {
$scope.model=null;
};
};
}
</script>
</head>
<body>
<div ng-controller="cntrl">
<label>Бренды
<select ng-model="brand" ng-options="o.name for o in brands" ng-change='newBrand()'>
<option></option>
</select>
</label>
<label>Модели
<select ng-model="model" ng-options="o.name for o in models"></select>
</label>
</div>
</body>
</html>
Последний раз редактировалось ksa, 17.02.2015 в 16:53.
|
|
17.02.2015, 16:52
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,217
|
|
capscom, сдается мне ты эти следилки не к месту используешь...
|
|
17.02.2015, 17:01
|
Интересующийся
|
|
Регистрация: 28.08.2011
Сообщений: 28
|
|
Сообщение от ksa
|
capscom, сдается мне ты эти следилки не к месту используешь...
|
А в чем ошибка использования ? Вариант с ng-change, нравится больше)
|
|
|
|