Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$watch of nested directive is not triggered when form's onaftersave get called #764

Open
sinall opened this issue Dec 2, 2019 · 6 comments

Comments

@sinall
Copy link

sinall commented Dec 2, 2019

I'm trying to create a duration editor which could represent "x days x hours x minutes x seconds" for a number which stores total seconds.

So the model totalSeconds is a number, and I create object duration of class Duration in the directive, then use 4 editable-text for those 4 properties.

In link method of the directive, I create scope.duration model and watch the object duration, the callback recalculates and updates the binding model totalSeconds.

When saving,

  1. duration.days gets called first
  2. form's onaftersave gets called
  3. $watch callback for duration (or duration.days) gets called

So I'm not able to save the updated totalSeconds in step 2.

Is there a way to let step 3 done before step 2?

@sinall
Copy link
Author

sinall commented Dec 2, 2019

Currently I have to use $timeout with 1 second delay in onaftersave to let $watch callback run first.

@ckosloski
Copy link
Contributor

Maybe use onbeforesave instead?
A plunker/jsfiddle might be useful as well to see what the issue is.

@sinall
Copy link
Author

sinall commented Dec 3, 2019

@ckosloski
Copy link
Contributor

I took a look at this and didn't see anything obvious.
Using setTimeout does fix the issue

setTimeout(function () {
    alert("validatyPeriod: " + $scope.validatyPeriod + " seconds");
  }, 100);

Couldn't find anything else that worked.

@sinall
Copy link
Author

sinall commented Dec 4, 2019

When you submit editable form it performs following steps:

  1. call child's onbeforesave
  2. call form's onbeforesave
  3. write data to local model (e.g. $scope.user)
  4. call form's onaftersave
  5. call child's onaftersave

I guess the problem occurs in step 3.

@sinall
Copy link
Author

sinall commented Dec 6, 2019

For someone meets the same problem, here's what I'm doing now as a workaround:

link: function(scope, element, attrs) {
 	// ...
	var formElement = element.parents('form');
	var oldCallbackName = formElement.attr('onaftersave').replace('()', '');
	var oldCallback = formElement.scope()[oldCallbackName];
	formElement.scope()[oldCallbackName] = function() {
		$timeout(function() {
			oldCallback();
		}, 100);
	};
},

By using this approach, you don't need to change the form's onaftersave callback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants