meteor / blaze

:fire: Meteor Blaze is a powerful library for creating live-updating user interfaces
http://blazejs.org/
Other
526 stars 114 forks source link

Components #128

Closed mitar closed 3 years ago

mitar commented 7 years ago

So once we will have template be an extendable class (#98), and one will be able to use their own base class as a template base, doing something like:

<template is="MyTemplateBase">
</template

or (see #122):

<MyTemplateBase>
</MyTemplateBase

The idea is that we provide core base class called Component (with tag component) which will provide new Blaze defaults for Blaze templates. Some ideas are:

We will probably have much more discussion in the future what exactly should be part of this basic component, but this issue is here to mostly explain the approach of keeping both backwards compatibility and providing new improvements to Blaze at the same time.

aadamsx commented 7 years ago

Check out this podcast with the builder of Vue.js, Evan You. He goes into some technicals, reasoning, etc. He talks about Components too.

It seems blaze is in for a remake of sorts, so now is the time to take in all perspectives. We might be able learn something from this library that will benefit Blaze.

mitar commented 7 years ago

Feel free to post your summary of the podcast/highlights you find illuminating here. :-)

aadamsx commented 7 years ago

Here's the official Vue.js 2.0 announcement.

A few highlights for the tl;dr:

UPDATE:

mitar commented 7 years ago

Yes, I really love the direction Vue is going. I really do not get how Meteor didn't do some path towards Vue from Blaze. They look pretty compatible and with a bit of effort it some way to merge and transition would be possible. They are definitely showing that there is still space for rendering libraries beyond React.

aadamsx commented 7 years ago

I really love the direction Vue is going

Indeed, and the momentum it has seems to be increasing. Evan You is working full time on the project (I got that from the podcast), only surviving off of donations and side-consulting.

Evan has even managed to outperform React 15.3.1:

1-lu6ojirajyshl4abppoh3w

Roughly speaking, It seems Vue 2.0 has most things we are wishing for in Blaze 2.0 and maybe more, thereby duplicating efforts...

Crazy idea, just thinking outside the box, what if Blaze 2.0 was a lightweight wrapper/abstraction on Vue 2.0? What if this wrapper was meant to ease the switch from Blaze 1.0 to "Blaze 2.0" with Syntax sugar, Tracker/Minimongo integration, tight integration with Meteor where possible, etc.?

mitar commented 7 years ago

Yea, potentially this could be a transition path. It would require some effort, but it could potentially work. In some way Blaze templates are already a wrapper around Blaze views. So maybe we could switch views with vue. But this is probably also something @yyx990803 would be better at knowing how to do. I think he probably looked into Blaze as well, so he could easier tell how possible something like that would be.

mitar commented 7 years ago

@aadamsx: I would love it you (or somebody) else could add vue.js implementations to my benchmarking app. It would be really great to compare it there because I have some examples there which are known to be hard for Blaze.

aadamsx commented 7 years ago

What do you think @yyx990803 (Evan), is there a chance for collaboration between Vue 2.0 and Blaze 2.0?

yyx990803 commented 7 years ago

@aadamsx @mitar hey guys, as much as I would love to help, I probably don't have bandwidth for more than providing feedback on general design directions.

Technically, yes you can compile Blaze template into Vue 2.0 render functions. To determine feasibility it would require some experimentation though.

msavin commented 7 years ago

That's interesting. I believe originally MDG wanted to build Blaze 2 as a wrapper around React, but maybe Vue is even better aligned for this job.


Back to the subject of components, that syntax (and the referenced issue) confuse me, and could potentially clash with WebComponents. Also - it's hard for me to grasp the use case here as handlebars could already achieve this?

Could you create sort of a "pseudo-documentation" so that we can better understand and discuss where you're thinking of taking this?

aadamsx commented 7 years ago

Didn't mean to sidetrack this thread, I moved talk of Vue and Blaze 2.0 to https://github.com/meteor/blaze/issues/131

murillo128 commented 7 years ago

Hi all,

I have beeing working arround this for a bit. So here are my 2 cents on this:

My idea was basically extending the HTML collection with custom tag elements, allowing to register new html elements that would be processed on runtime as any other template. It is better seen with an example I have been putting together to wrap material design lite into custom tag elements (with namespacing):

        <mdl:table>
        <mdl-table:head>
            <mdl-table:tr>
                <mdl-table:th non-numeric>Name</mdl-table:th>
                <mdl-table:th sorted="ascending">Num</mdl-table:th>
                <mdl-table:th sorted="descending">Total</mdl-table:th>
            </mdl-table:tr>
        </mdl-table:head>
        <mdl-table:body>
{{#each item}}
            <mdl-table:tr>
                <mdl-table:td non-numeric>{{name}}</mdl-table:td>
                <mdl-table:td>{{num}}</mdl-table:td>
                <mdl-table:td>{{total}}</mdl-table:td>
            </mdl-table:tr>
{{/each}}
         </mdl-table:body>
    </mdlf:table>

The code to have it running is quite small:

//Register custom element function
HTML.registerElementTemplate = function(namespace,name,templateFunc)
{
    var fullName = namespace + ":" +name;

    var template = new Blaze.Template(fullName,templateFunc);

    //Add helpers to template
    template.helpers({
        'has' : function(obj,name) {
            return obj.hasOwnProperty(name);
        }
    });

    HTML[HTML.getSymbolName(fullName)] = function(){
        var i = 0;
        var attributes = {};
        var content = [];
        var arg = arguments.length && arguments[0];
        if (arg && (typeof arg === 'object')) 
        {
            // Treat vanilla JS object as an attributes dictionary.
            if (! HTML.isConstructedObject(arg)) 
            {
                attributes = arg;
                i++;
            } else if (arg instanceof HTML.Attrs) {
                var array = arg.value;
                if (array.length === 1) 
                    attributes = array[0];
                else if (array.length > 1)
                    attributes = array;
                i++;
            }
        }

        // If no children, don't create an array at all, use the prototype's
        // (frozen, empty) array.  This way we don't create an empty array
        // every time someone creates a tag without `new` and this constructor
        // calls itself with no arguments (above).
        if (i < arguments.length)
            content = Array.prototype.slice.call(arguments, i);

        var view = template.constructView(function(){ 
            return content;
        });

        //Create atrribute list witthout class
        var ATTRIBUTES = {};
        //Copy everything
        for (var key in attributes)
            //Except class
            if (key!=="class")
                //Copy
                ATTRIBUTES[key] = attributes[key];

        //Add also the data type
        ATTRIBUTES["data-" + namespace] = name;

        //Append
        attributes.ATTRIBUTES = ATTRIBUTES;

        //Add binding
        Blaze._attachBindingsToView(attributes,view);

        return view;
    };

    return template;
};

This way you are able to register a template function to be rendered when the element name is found in the template:

<template name="MaterialIcon">
    <i class="material-icons {{class}}" {{ATTRIBUTES}}>{{> Template.contentBlock}}{{/if}}</i>
</template>

<script>
    HTML.registerElementTemplate("mdl","icon",Templates["MaterialIcon"]);
</script>

Note that the returned value of registerElementTemplate is a template, so you can set callbacks and helpers accordingly.

As I said it is still a work in progress, and I have it only working with my jquery blaze plugin . But if you find it usefull, I could collaborate on having it done propertly.

filipenevola commented 3 years ago

I'm closing this issue because it's too old.

If you think this issue is still relevant please open a new one.

Why? We need to pay attention to all the open items so we should keep opened only items where people are involved.