angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.84k stars 27.51k forks source link

Proposal: pluggable parsers #2908

Open andershessellund opened 11 years ago

andershessellund commented 11 years ago

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

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 commented 11 years ago

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 commented 11 years ago

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

andershessellund commented 11 years ago

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 commented 11 years ago

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 ( https://github.com/angular/angular.js/issues/768 ) and this plunkr: http://plnkr.co/edit/c863Z267jdM7KygfBUi8 .. the accessor is actually the most needed if I can trust #768 :)