5

I have this situation where I need to capture the event when a model is changed but the initialization in my directive triggers the event too early.

Plunker: http://plnkr.co/edit/2T0Rq6yOXHWxQAOv8RpX?p=preview

How can I overcome this? Setting some flags, but how/where? Other approaches?

Thanks!

UPDATE

I added the value attribute to the directive so you can understand better what I mean by initialization.

Plunker: http://plnkr.co/edit/a5fzJi7VzAytj3Urj06L?p=preview

2
  • 1
    Can you explain what you mean by "too early" Commented Feb 3, 2014 at 14:35
  • @DavinTryon My directive checks if the model is defined. If not, it initializes the model with "0". But this change/initialization triggers the $watch from the controller and I don't want this as it is now a real change from the user. Commented Feb 3, 2014 at 14:38

3 Answers 3

3

I solved it finally!

Plunker: http://plnkr.co/edit/a5fzJi7VzAytj3Urj06L?p=preview

The form directive in Angular has a property called $dirty. It starts as false and when you change the value of an input, the ngModel directive makes the form "dirty". First I tried to use ngModel in my directives but I ended up requiring using the form directly.

PS. This is triggered only on the first change, but this is exactly what I needed.

Sign up to request clarification or add additional context in comments.

3 Comments

You didn't have a form element in your initial sample.
I know :( It's because I tried to simplify the question as much as possible.
Nice, I was puzzled with this problem too. Thanks for sharing!
1

You define data as

$scope.data = { x: 51 }

Later during parsing Angular detects that there are two more properties: y and z and they are undefined. In directive you set them to 0 in this case. So your data object becomes

{ x: 51, y: 0, z: 0 }

Obviously that $scope.data has changed and watcher should fire. This is why it happens.

To solve this you can simply define data with initial y and z values:

$scope.data = { x: 51, y: 0, z: 0 };

Demo: http://plnkr.co/edit/RfztKvrxhzPYMoSss7Fm?p=preview

4 Comments

I understand why it happens :) I just need a way to overcome this without setting initial values in data, because I don't know what properties should be set in the controller.
Well then you can also compare number of data properties in the old and new values. plnkr.co/edit/RfztKvrxhzPYMoSss7Fm?p=preview. You only want to fire watcher if this number is the same, meaning that property changed but not added (if it was undefined before).
Thanks! Your solution works, but isn't it a little hacky? If I add a new value it won't be triggered. plnkr.co/edit/vTyrejMdrFh6Dty98USI?p=preview
I agree that it's not ideal. Trying to come up with better approach.
0

You could check if a property exists on an object. demo

 if ((newValue !== oldValue) && oldValue.x) {

or maybe a more precise demo:

if ((newValue !== oldValue) && (typeof oldValue.x !== 'undefined')) {

3 Comments

The properties may change, so I can't check on that.
But you check if the property is defined or undefined. In your statement data = {} the properties x,y,z are initially undefined and then setting them to 0 or any other number they are defined.
Your solution requires me to know at least one of the properties, which I don't know. Also you assume everything is initialized in one digest cycle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.