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

これが管理上どのように機能するかはわかりませんが、どういうわけか、複製からの回答をこれとマージする必要があります。bresleveloperは(重複から)優れたソリューションですが、TGHの回答も表示する必要があります。1つ目はフレームワークの動作に依存しますが、2つ目はフレームワークに依存しません。
user1821052

回答:


279

角のある{{expression}}を使用すると、古いユーザーまたは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の最初の引数は新しいユーザー値になり、2番目の引数は、select-tagが角度によって最後に更新されたときに形成されたリテラルで、古いuser.id値になります。


6
userinメソッドの呼び出しは、ng-modelng-optionsからではなく、からのものであることに注意してください(誤解を招く可能性があります)。うまくいけば、このエレガントなソリューションは、angularの将来のバージョンでも機能します:)
icl7126

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
美しい:))))
マカトゥン2018年

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 2017

14

ng-change = someMethod({{user.id}})のようなものを使用できます。値を{{expression}}側に保持することで、式をインラインで評価し、現在の値(ng-changeメソッドが呼び出される前の値)を提供します。

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

13

すべての変更で更新するcurrentValue変数をコントローラーに保持するだけです。その後、更新する前に毎回それを新しい値と比較できます。

時計を使用するという考え方も良いですが、単純な変数が最も単純で最も論理的な解決策だと思います。


時計は少し高価な操作です、私はdb-infの答えが好きでした..それは単純な作業ソリューションです
Pramod Sharma

4
ベストアンサー。ng-repeat内にいる場合は、ng-initを使用してサブスコープに変数を作成します。
Romain 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と比較して、watchの方がはるかにダーティ/非効率的であると述べている記事に出くわしました。benlesh.com/2013/10/title.html
Menios

5
私の経験では、ほとんど時計を使いたくない
nardnob

2
プログラミングが主観的な芸術であれば、そこに何かがあるかもしれません。悲しいかな-ng-chargeや他のディレクティブベースのアプローチを避けたいと思う理由はたくさんあります。
tommybananas

2

古い値と新しい値があるため、代わりに時計を使用できますが、ダイジェストサイクルに追加します。

コントローラーに2番目の変数を保持し、それを設定するだけです。


これはかなり簡単な例です。この例では、1つのウォッチャーを心配することよりも読みやすくしています。それでも、うんざりするのは良いことだと思います。
tommybananas 2014年

1
ウォッチとng-changeの実際の動作は異なります。ng-changeはユーザーイベントのみを検出しますが$watch、変数が変更されるたびに発生します。ウォッチャーは複雑さを増し、コードが値を変更するときに更新サイクルを作成する傾向があります。
Rhys van der Waerden、2015年

@Rhys van der Waerdenに同意します...この記事では、$ watchは少し危険だと述べています:benlesh.com/2013/10/title.html
Menios
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.