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

Odd way of getting $formatters to run in a directive #12022

Closed
geuis opened this issue Jun 4, 2015 · 3 comments
Closed

Odd way of getting $formatters to run in a directive #12022

geuis opened this issue Jun 4, 2015 · 3 comments

Comments

@geuis
Copy link

geuis commented Jun 4, 2015

I spent hours reading through documentation, blog entries, and Stackoverflow questions to try and answer the question, "How do you get $formatters to run and update the view in directives?".

There is no clear answer that I could find. The directive demo on the documentation page itself doesn't even use any of the $parsers, $formatters, etc on the very page.

Regardless, I was able to get it to work like this: http://plnkr.co/edit/R7HkCJhmJ43KK03LkOmU

app.directive('uppercase', [
  function () {
    return {
      require: 'ngModel',
      link: function ($scope, $element, $attr, $controller) {
        $controller.$parsers.push(function (viewValue) {
          return viewValue.toLowerCase();
        });

        $controller.$formatters.push(function (modelValue) {
          return modelValue.toUpperCase();
        });

        $controller.$viewChangeListeners.push(function () {
          $controller.$modelValue = '';
        });
      }
    }
  }
]);

Setting the $controller.$modelValue to an empty string triggers the formatters and automatically updates the view without needing to call $setViewValue, $render, etc.

I believe this is the closest approach to how most people imagine this should all work, but it is in no way obvious that this should work at all.

I'm not sure if I should submit a pull request to update the documentation for this example, or if there is a better way to do it and this should be fixed.

@ryanhart2
Copy link
Contributor

There are two open issues #11714 & #8194 related to improving the documentation for $parsers and $formatters.
There is also an open issue #10764 for a new ngModelController method that will allow $formatters to be run manually. I think that you would still need to call it from within $viewChangeListeners, but at least the code would be more readable:

ctrl.$viewChangeListeners.push(function () {
  ctrl.$format(); // assuming that this is what the new method is called
});

@Narretz
Copy link
Contributor

Narretz commented Jun 5, 2015

Yes, there is currently no way to run the formatters programatically. We are looking into that (again) for 1.5.
When you look at the source, it's actually just that bit of code. You can use that in the meantime.

      var formatters = ctrl.$formatters,
          idx = formatters.length;

      var viewValue = modelValue;
      while (idx--) {
        viewValue = formatters[idx](viewValue);
      }
      if (ctrl.$viewValue !== viewValue) {
        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
        ctrl.$render();
      )

@VRMink
Copy link

VRMink commented Nov 10, 2015

This has also been an issue for me. Only looking through the "issues" here on GitHub gave me an indication of the reason for the behaviour. Before there is a fix available in the API or otherwise, we should atleast not close these issues down, and we should update the documentation be descriptive.

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