This is an extension of @ Emmanuel's answer above to answer @Martin Velez, although I know it's pretty late! (Also I can't make comments yet, so if this isn't the right place for this, sorry!)
I'm not sure which version of Angular OP was using, but in Angular#1.2+ at least on the official docs https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$render, $render is listed like this:
Called when the view needs to be updated. It is expected that the user
of the ng-model directive will implement this method.
The $render() method is invoked in the following situations:
$rollbackViewValue() is called. If we are rolling back the view value
to the last committed value then $render() is called to update the
input control. The value referenced by ng-model is changed
programmatically and both the $modelValue and the $viewValue are
different from last time. Since ng-model does not do a deep watch,
$render() is only invoked if the values of $modelValue and $viewValue
are actually different from their previous value.
I interpret this to mean that the correct way to $watch an ngModel from a directive is to require ngModel and implement a link function that injects ngModelController. Then use the ngModel API that's built in to $render-on-change ($watch), or whatever else.