ng-change获得新值和原始值


118

我正在使用ng-options从下拉列表中选择值。我希望能够将旧值与新值进行比较。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是BILL,您的当前用户名为PHILLIPE”。


1
在这里检查我的答案stackoverflow.com/questions/21909163/… 可能重复
bresleveloper 2015年

不确定这在管理上是如何工作的,但应以某种方式将重复项的答案与此合并。bresleveloper是一个不错的解决方案(重复),但也应显示TGH答案。第一个依赖于框架的工作,将来可能会发生变化,而第二个则与框架无关。
user1821052 '02

Answers:


279

使用有角的{{expression}},您可以将原先的user或user.id值作为文字字符串添加到ng-change属性中:

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

在ngChange上,updateValue的第一个参数将是新的用户值,第二个参数将是上次用角度更新select-tag并使用旧的user.id值时形成的文字。


6
请注意,userin方法调用是来自ng-model而不是ng-options的调用(可能会引起误解)。希望这种优雅的解决方案也可以在angular的未来版本中使用:)
icl7126'3

15
这应该被认为是有害的。我刚遇到user.id包含特殊字符(例如'或/)时发生的肮脏错误,这是因为Angular表达式解析器不喜欢updateValue(user,'blah / blah')这样的表达式。
Antoine Banctel-Chevrel,2015年

2
在功能updateValue,$ scope.user.id已经包含新选择的价值-没有必要通过一个参数的新值给它
Majix

@ LINQ2Vodka,我认为它只有在user.id数字不加引号的情况下才能使用...如果user.id是字符串或GUID ,它将不起作用
Tamas

1
美丽:))))
Makatun

16

你也可以用

<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-change但不支持ng-focus,则也可以使用ng-click代替。
meticoeus

1
ng-init =“ oldValue = 0”和ng-focus =“ oldValue = user.id”对我有用。
thatzprem

14

您可以使用类似ng-change = someMethod({{user.id}})的名称。通过将值保留在{{expression}}一边,它将在线评估表达式并为您提供当前值(调用ng-change方法之前的值)。

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

13

只需在您的控制器中保留currentValue变量,即可在每次更改时进行更新。然后,您可以在每次更新之前将其与新值进行比较。”

使用手表的想法也很好,但是我认为简单的变量是最简单,最合乎逻辑的解决方案。


手表操作成本不高,我喜欢db-inf的回答..这是简单的工作解决方案
Pramod Sharma 2015年

4
最佳答案。如果您在ng-repeat中,请使用ng-init在子作用域中创建一个变量。
罗曼·F。

1
恕我直言,这是最好的选择。由于ngChange不能立即提供检索旧值的功能,因此@ db-inf中的解决方案可能会在将来的版本中崩溃。此外,这听起来像控制器的责任,将其委托给视图层似乎很奇怪。
FelipeLeão17年

9

您可以使用示波器监视:

$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相比,手表的肮脏程度/效率低得多。benlesh.com/2013/10/title.html
Menios 2015年

5
根据我的经验,您几乎永远都不想使用手表
nardnob

2
如果编程是一门主观艺术,那么您可能会在这里有所收获。las-您可能有很多理由想要避免使用ng-charge或其他基于指令的方法,而这些方法与“角度”方式无关。
tommybananas

2

您可以改用手表,因为它具有旧值和新值,但随后又增加了摘要周期。

我只是将第二个变量保留在控制器中并进行设置。


这是一个非常琐碎的示例,在这种情况下,我会为避免担心单个观察者而采用可读性。我想这还是一件好事。
tommybananas 2014年

1
Watch和ng-change实际上具有不同的行为:ng-change仅检测用户事件,而$watch每次变量更改时都会触发。观察者增加了复杂性,并且在代码更改其值时倾向于创建更新周期。
Rhys van der Waerden 2015年

我同意@Rhys van der Waerden ...这篇文章指出$ watch有点危险:benlesh.com/2013/10/title.html
Menios
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.