Polymer / polymer

Our original Web Component library.
https://polymer-library.polymer-project.org/
BSD 3-Clause "New" or "Revised" License
22.04k stars 2.01k forks source link

Ternary operator in binding expressions #4038

Closed StokeMasterJack closed 7 years ago

StokeMasterJack commented 7 years ago

This would be a nice thing to have:

[[prop?'yes':'no']]

without having to write a function.

miztroh-zz commented 7 years ago

Something like this would get really complicated. For example, you could have property named that same string:

{
    properties: {
        "prop?'yes':'no'": {
            type: Boolean,
            value: true
        }
    }
}

If you're needing this functionality a lot, I would just make it part of a behavior:

var YourProject = YourProject || {};

YourProject.TernaryBehavior = {
    ternary: function (a, b, c) {
        return a ? b : c;
    }
};

Then just include that behavior anywhere it's needed.

web-padawan commented 7 years ago

This was deprecated since 0.5, as well as filters etc.

StokeMasterJack commented 7 years ago

I don't know how hard it would be to implement it. But JSP has it. Angular has it. React has it. In fact, it React you can use any arbitrary JS expression.

TimvdLippe commented 7 years ago

This has been requested a couple of times already and the reason it was deprecated since 0.5 is the performance impact. While ternary operator is useful, so are concatenation, equals, etc... Therefore you have to support a multitude of operators which greatly increase the amount of time required for every single binding the library encounters.

The possibility of supporting an opt-in expression syntax parser was originally developed at https://github.com/Polymer/polymer-expressions but discontinued for reasons I do not know, but most likely performance. With Polymer 2.0 it might be possible to allow users to define mix-in classes that can parse various operators you can define as a developer yourself. The core dev team would need to comment on that possibility.

larsgk commented 7 years ago

It might be that having expressions and filters introduce a performance hit where used - but from a development standpoint, it's VERY useful to have.

Some examples:

With the current "solution" in 1.x, you will need something like a super-master-behavior, inherited by ALL elements (including built-in) that has a ton of functions to compensate for missing filters and expressions - OR make custom functions and inheritance of built in elements all over. In any case, the templates will become filled with function calls and it will not be easy to understand the exact behavior at first glance. In the larger web projects, I've been working on (angular & some ember), I'd say filters were used in maybe 25% of the rendered bindings to make things easily localizable, custom formatted, etc. + the occational simple calculation or bit mask.

Last: One could (sarcastically) argue that attributes slow down processing as well - and we should only be left with the custom tags (sans attributes) - because: "performance"... and if needed: "just make more custom elements for each specific need".

PPS: I work for a company where we are looking into a few UI and app frameworks for the NextBigThing(TM). Not having expressions and filters (as well as missing singletons/services, etc.) makes polymer hard to sell...

web-padawan commented 7 years ago

@larsgk don't fotget that Polymer is a library, not a framework. It shouldn't enforce you to use some formatters. There are other libraries for this, e. g. Intl.js etc, and those can be wrapped in behaviors like you mentioned.

Using ternary operators etc. in 0.5 means parsing data-bindings in runtime, just open dev tools and you'll see those {{ a ? b : c }} right there inside of attribute values.

larsgk commented 7 years ago

@web-padawan Making filters like e.g. angular wouldn't enforce specific formatters - they can be custom injects and I think the ones included are mainly there as examples/because they are very common.

In general, even if it's not a framework, I am sure many will see it and use it as such - AND could benefit from (at least) solid guides on how to get around the gaps (e.g. missing expressions, filters, singletons and more) on the project web page.

larsgk commented 7 years ago

fyi - my temporary fix until fixed in polymer2:

{{_eval('1 - 2')}} = {{_eval('Math.floor(1.2) - this._gimme2()')}}

Result: "-1 = -1"

with

...
_gimme2: function() {
    return 2;
},

_eval: function(str) {
    return eval(str);
},
...

Do I like it: no Is it necessary to not go insane without expressions/filters/etc.: yes

web-padawan commented 7 years ago

I believe in separate concerns: logic should be in JS and HTML is for markup. Actually I'm working on moving Polymer 0.5 project to 1.x and previously there were a lot of ternary operators (e. g. in the body passed to core-ajax elements). All this stuff makes me sad when it comes to refactor.

Another ting, there is a big work now with polymer-analyzer, which is used to parse elements and detecting data bindings as well as other features (properties, computed functions). Re-implementing filters and operators might require a lot of changes there.

kevinpschaaf commented 7 years ago

We're much more inclined to make Polymer's template syntax pluggable than we are to pick and choose new syntax to add, so that the community is empowered to drive that. That said, it's non-trivial to make a good pluggable abstraction that doesn't slip in performance, etc. So far we're keeping most of the template parsing & binging effects code private, until we can ensure the extension points we have are robust, and then we hope to open that up for e.g. mixin authors to provide new features. Unclear whether we'll get there by the final 2.0 release or if that would come after, but that's our general direction.

We have a tracking bug for this request here: https://github.com/Polymer/polymer/issues/3369. Closing this issue as a duplicate.