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

Proposal: pluggable parsers #2908

Open
andershessellund opened this issue Jun 8, 2013 · 4 comments
Open

Proposal: pluggable parsers #2908

andershessellund opened this issue Jun 8, 2013 · 4 comments

Comments

@andershessellund
Copy link
Contributor

Sometimes, it would be useful to be able to change how an expression is parsed. This would fix a number of problems, such as:

  • Enable the possibility of using an accessor function in a ng-model expression. (Allow binding to getter/setter fn #768)
  • Evaluate an expression in the parent scope in order to escape an isolate scope (e.g., if you want to use ng-show on the same element as a directive with isolate scope). (Adding ngModel. #2904)
  • Enable simpler syntax for specialized use cases, e.g. for i18n.

This could be done by introducing a new concept, which for now I will just call "parser filters". A parser filter is simply a function, which takes a string (the expression to be parsed) as an argument, and returns the parsed expression.

$parse would have to be extended such that it can understand parser filters. I propose a syntax like follows:

<input ng-model="``accessor obj.property($value)">

The _accessor_ part specifies that the expression that follows should be parsed by the "accessor" parser filter. I'm sure others can come up with a better syntax. So $parse would simply pick up the fact that the expression starts with , then it would read the parser filter name, and pass the rest of the expression (as a string) to the parser filter.

The "accessor" parser filter would be implemented like this:

      module.parserFilter('accessor', function($parse) {
        return function(expression) {
          var result = $parse(expression);
          result.assign = function(context, value) {
            result(context, {$value: value});
          }
          return result;
        };
      });

So, parser filters can be really simple to implement, and in most cases will probably use $parse to do the actual parsing. It would also be reatively simply to implement java-style getProperty/setProperty accessor functions.

There are probably many other use cases for parser filters, they seem to me to be a very flexible feature.

@mprobst
Copy link
Contributor

mprobst commented Jun 20, 2013

This sounds interesting, but can you expand a bit more on the possible use cases? The accessor for ng-model could also be solved locally for the ng-model, and I think I don't get the $parent use case (the user would still have to type something, so whether it's ``parent or .$parent doesn't matter, does it?) or the i18n.

I think I just don't quite see the general pattern of transforming an expression like this.

@basarat
Copy link
Contributor

basarat commented Jul 5, 2013

Agreed $parent for ngmodel is just as sufficient as this.

@andershessellund
Copy link
Contributor Author

OK, ``parent was a really bad example.

Nonetheless, a way to specify jquery-style accessor functions and also get/set accessor style functions are - in my opinion very useful. And support for this should IMO be implemented in $parse, not in ng-model.

I think a specific parser for i18n would result in a more concise syntax. For example, one might write a service that can translate a key to a translation in the chosen language of the user. Rather than having to write an expression such as "$translationService.translate('loginform.username')" or something like that, it would be nicer have a concise syntax for this, such as "``translate loginform.username".

It would be even better if a custom parser could also provide the mechanism for dirty-checking the expression. translations of texts only changes when the user changes the current language - and the $translationService would know exactly when that happens. Dirty-checking in every digest cycle is really wasteful in this case.

@abourget
Copy link

Woah, that'd be neat :) Control the dirty checking.. we could finally get something less hacky for i18n.

Also, I often implement what I call "watch killers", which set things into place (setHtml, setText, setClass, etc..) but don't call $watch .. for things I know won't change.. adding a prefix to prevent further dirty checks (or make them vverrry fast) would be awesome.

The accessor thing is also really useful. @tomsdev already implemented a quite nice solution with ES5 get/set accessors in this issue ( #768 ) and this plunkr: http://plnkr.co/edit/c863Z267jdM7KygfBUi8 .. the accessor is actually the most needed if I can trust #768 :)

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

6 participants