2014-10-29 4 views
89

Я использую ng-options для выбора значений из раскрывающегося списка. Я бы хотел, чтобы сравнить старое значение с новым значением. ng-change хорошо работает для захвата нового значения спуска, но как я могу получить как новое значение, так и исходное значение?ng-change получить новое значение и исходное значение

<select ng-change="updateValue(user)" ng-model="user.id" ng-options="user.id as user.name for user in users"></select> 

Например, скажем, я хотел контроллер войти, «Ваш бывший user.name был ЗАКОНОПРОЕКТ, текущее имя пользователя PHILLIPE.»

+1

проверить мой ответ здесь http://stackoverflow.com/questions/21909163/get-old-value-and-new-value-from-dropdown/28296355 # 28296355 может быть дубликат – bresleveloper

+0

не уверен, как это работает административно, но почему-то ответы из дубликата должны быть объединены с этим. bresleveloper - хорошее решение (из дубликата), но также должен быть показан ответ TGH. Первый основан на работе каркаса, который может измениться в будущем, а второй - агностик. – user1821052

ответ

236

С угловой {{выражение}} вы можете добавить старый пользователь или user.id значение атрибута нг-изменения в виде символьной строки:

<select ng-change="updateValue(user, '{{user.id}}')" 
     ng-model="user.id" ng-options="user.id as user.name for user in users"> 
</select> 

На ngChange, 1-й аргумент updateValue будет быть новым значением пользователя, второй аргумент будет литералом, который был сформирован, когда тег select был последним обновлен угловым, со старым значением user.id.

+5

Обратите внимание, что вызов 'user' в методе является одним из «ng-model», а не из ng-options (может вводить в заблуждение). Надеюсь, это элегантное решение будет работать и в будущих версиях угловых :) – icl7126

+11

Это должно считаться вредным. Я просто наткнулся на грязную ошибку, возникающую, когда user.id содержит специальный символ (например, «или»). Это потому, что синтаксический анализатор углового выражения не любит выражения типа updateValue (пользователь, «бла-бла»). –

+1

В функции updateValue $ scope.user.id уже содержит новое выбранное значение - нет необходимости передавать параметр для нового значения в него – Majix

11

Просто сохраните переменную currentValue в контроллере, которую вы обновляете при каждом изменении. Затем вы можете сравнить это с новым значением каждый раз, прежде чем обновлять его ».

Идея использования часов также хороша, но я думаю, что простая переменная является самым простым и наиболее логичным решением.

+0

Смотреть немного дорогой операции, мне понравился ответ db-inf .. это простое рабочее решение –

+3

Лучший ответ. Если вы находитесь внутри ng-repeat, создайте переменную в поддиапазоне, используя ng-init. –

+0

ИМХО это лучшая альтернатива. Поскольку получение старых значений не обеспечивается ngChange из коробки, такие решения, как один из @ db-inf, могут взорваться в будущих версиях. Кроме того, это звучит как ответственность диспетчера, кажется странным делегировать его на уровень представления. –

8

Вы можете использовать области видимости часы:

$scope.$watch('user', function(newValue, oldValue) { 
    // access new and old value here 
    console.log("Your former user.name was "+oldValue.name+", you're current user name is "+newValue.name+"."); 
}); 

https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

+6

Я столкнулся с статьей, в которой говорится, что часы намного грязнее/неэффективны по сравнению с ng-change. http://www.benlesh.com/2013/10/title.html –

+4

По моему опыту вы почти никогда не хотите использовать часы – nardnob

+1

Если программирование было субъективным искусством, у вас могло быть что-то.Увы, есть много причин, по которым вам может понадобиться избегать ng-charge или других подходов, основанных на директивах, не связанных с тем, что они делают «угловой» способ. – tommybananas

2

Вы можете использовать часы вместо этого, потому что есть старое и новое значение, но тогда вы добавляете к циклу дайджеста.

Я бы просто сохранил вторую переменную в контроллере и установил ее.

+0

Это довольно простой пример, я бы воспринял читаемость, опасаясь за одного наблюдателя в этом случае. По-прежнему хорошо, что я устал от этого. – tommybananas

+1

Часы и ng-change действительно имеют разные типы поведения: ng-change определяет только пользовательские события, тогда как '$ watch' будет срабатывать каждый раз при изменении переменной. Наблюдатели увеличивают сложность и склонны к созданию циклов обновления, когда код меняет свои значения. –

+0

Я согласен с @Rhys van der Waerden ... в этой статье говорится, что $ watch немного опасен: http://www.benlesh.com/2013/10/title.html –

7

Вы можете использовать что-то вроде ng-change = someMethod ({{user.id}}). Сохраняя ваше значение в стороне {{выражение}}, он будет оценивать выражение в строке и дает текущее значение (значение до вызова метода ng-change).

<select ng-model="selectedValue" ng-change="change(selectedValue, '{{selectedValue}}')"> 
8

Также вы можете использовать

<select ng-change="updateValue(user, oldValue)"  
     ng-init="oldValue=0" 
     ng-focus="oldValue=user.id" 
     ng-model="user.id" ng-options="user.id as user.name for user in users"> 
</select> 
+1

Этот ответ очень хорошо работает с ng-repeat. Вы также можете использовать ng-click, если элемент, который вы используете для этого, поддерживает ng-change, но не ng-focus. – meticoeus

+0

ng-init = "oldValue = 0" & ng-focus = "oldValue = user.id" сделал трюк для меня. – thatzprem

Смежные вопросы