$watch of nested directive is not triggered when form's onaftersave get called
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,
-
duration.daysgets called first - form's onaftersave gets called
- $watch callback for
duration(orduration.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?
Currently I have to use $timeout with 1 second delay in onaftersave to let $watch callback run first.
Maybe use onbeforesave instead?
A plunker/jsfiddle might be useful as well to see what the issue is.
http://jsfiddle.net/e974t8qr/3/
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.
When you submit editable form it performs following steps:
- call child's onbeforesave
- call form's onbeforesave
- write data to local model (e.g. $scope.user)
- call form's onaftersave
- call child's onaftersave
I guess the problem occurs in step 3.
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.