Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ngModel.$setViewValue should return a promise #11423

Closed
wesleycho opened this issue Mar 25, 2015 · 8 comments
Closed

ngModel.$setViewValue should return a promise #11423

wesleycho opened this issue Mar 25, 2015 · 8 comments

Comments

@wesleycho
Copy link
Contributor

In the case of a debounced value update, currently $setViewValue does not allow the user to detect when the update is truly executed, resulting in a potentially premature call to $render - this affects the UI Bootstrap datepicker. If ngModelOptions has no debounce, it should then resolve immediately.

The usage should be promise based, so it can support code like

ngModel.$setViewValue('foo')
  .then(ngModel.$render);
@petebacondarwin
Copy link
Member

I can see that the use case is that you want to re-render the directive when the user interacts, which happens to occur when you hit $setViewValue but I am not sure whether this is the right way to go about this.

First of all, why does the widget need re-rendering, when you are writing to the $viewValue? Is it not the case that the rendering should be done irrespective of whether the value is finally written to the scope?

Or am I missing something? Is it that the $viewValue is failing to update due to the debounce? So when you re-open the date picker it is reading the "invalid" $viewValue and displaying that rather than the actual value?

@wesleycho
Copy link
Contributor Author

Currently we have code that executes $render right after $setViewValue in UI Bootstrap - this needs to change in order to properly support debouncing with ngModelOptions, but I want to avoid sniffing for what the user has set and do a $timeout based on that to execute the render.

What this means is that when $render is executed, since the $viewValue has not been updated, the $render function is using an older version of $viewValue when it executes.

@petebacondarwin
Copy link
Member

So a question to ask is are you using $render correctly in this case?

@wesleycho
Copy link
Contributor Author

I didn't write the code, so I can't say :) .

One would normally call $render after calling $setViewValue, no?

@Narretz
Copy link
Contributor

Narretz commented Mar 26, 2015

$setViewValue is generally called after the user changes an input: it extracts the value from the input and sets it on the ngModel. $render needs to be called after the model changes to update the input.
A common problem is that widgets format the $viewValue before it's set on the model, and they want to propagate this change back to the input, and for that they need $render.

@petebacondarwin
Copy link
Member

Really $render was never designed to be called by directives themselves, it is just a method for you can monkey patch to provide the rendering functionality that will be called by ngModelController when it deems that the widget needs to be re-rendered...

@wesleycho
Copy link
Contributor Author

I see - it would appear that UI Bootstrap likely is using $render & $setViewValue incorrectly here.

Closing as invalid.

@chrisirhc
Copy link
Contributor

Fyi, I did some digging into the usage of $render & $setViewValue in UI Bootstrap. The intention call the $formatters programmatically due to a change in configuration that would affect the formatting of the model value. A PR has been opened for that: #10764

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

No branches or pull requests

4 participants