Code Monkey home page Code Monkey logo

Comments (20)

hodeware avatar hodeware commented on May 9, 2024 1

But, @ref still a problem which only be fixed on version 3.

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024 1

That's correct.

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

This is the best place to send your questions. In the classes render does not return lemonade.element, only the template as the example below:

<html>
<script src="https://lemonadejs.net/v2/lemonade.js"></script>
<div id='root'></div>
<script>
class Counter extends lemonade.component {
    constructor() {
        super();
        this.count = 1;
    }
 
    counter() {
        this.count++;
    }
 
    render() {
        return `
            <>
            <div>Counter: {{self.count}}</div><br>
            <input type='button' onclick="self.counter()" value='Go' />
            <input type='button' onclick="self.count = 0" value='Reset' />
            </>
        `;
    }
}
lemonade.render(Counter, document.getElementById('root'));
</script>
</html>

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

I am creating an example for you....

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

It still does not work

<html>
<script src="https://lemonadejs.net/v2/lemonade.js"></script>
<div id='root'></div>
<script>

function FunctionComponent() {
    let self = this;
    let template = `<h1>{{self.title}}</h1>`;
 
    return lemonade.element(template, self);
}

class ClassComponent extends lemonade.component {

    render() {
        return `<h1>{{self.title}}</h1>`;
    }

}

function MainView() {
    let template = `<>
        <FunctionComponent title="Test message for function" />
        <ClassComponent title="Test message for class" />
    </>`;
 
    return lemonade.element(template, self, { FunctionComponent, ClassComponent });
}

lemonade.render(MainView, document.getElementById('root'));
</script>
</html>

IMHO it is better to create examples in the documentation rather than just for me

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

Yes, there a few examples worth uploading to the documentation. A new section for webcomponents will be added...

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

In the current version, the self for classes goes in the constructor where you need to do the merge. When I was doing some tests I noticed that @ref is not working correctly so you need to create the reference in the parent manually.

We are currently working on LemonadeJS v3, which this issue will be addressed.

    class Hello extends lemonade.component {
        constructor(self) {
            super(self);
            // Initial self
            Object.assign(this, self);
            // Keep the reference of this instance in the parent
            o.parent.hello = this;
        }

        render() {
            return `<h1>{{self.title}}</h1>`;
        }
    }

    function Test() {
        // Get the attributes from the tag
        let self = this;

        // Title and year are declared in the parent template
        let template = `<div>
            <Hello title="The very best of 2022" />
          <input type="button" onclick="self.hello.title = 'new title'" value="Change title"/>
          </div>`;

        return lemonade.element(template, self, { Hello });
    }

    lemonade.render(Test, document.getElementById('root'));

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

It is now unclear the scenario described in this issue report is a bug or a feature.

The snippet throws an error: ReferenceError: Can't find variable: o

Screenshot 2022-12-27 at 14 21 03

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

Sorry, my bad... change o.parent.hello to self.parent.hello = this

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

Cool, Object.assign() does the trick. The final version of a custom_HTML5_Web_Component to LemonadeJS_component wrapper using a ES6 class so far looks like this:

Edit: less code by first setting defaults, then applying attribute values.

export class KnobComponent extends lemonade.component {

    constructor(self) {
        super(self);

        // Defaults
        this.min = 0;
        this.max = 1;
        this.value = 0;

        // This will read values set by attributes
        // for example: <KnobComponent min="1" max="100" value="1" />
        Object.assign(this, self);
    }

    render() {
        return `<g-knob
                    min="{{self.min}}"
                    max="{{self.max}}"
                    @bind="self.value">
                </g-knob>`;
    }

}

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

More testing... initial state is now correctly set, but the component is not reactive. Just noticed this was sneaked into the example snippet, kinda defeats the purpose of the library...

      <input type="button" onclick="self.hello.title = 'new title'" value="Change title"/>

The only complete solution is to forget ES6 classes and use functions which is totally fine but undocumented:

export function KnobComponent() {
    let self = this;

    const template = `<g-knob
                        min="{{self.min}}"
                        max="{{self.max}}"
                        @bind="self.value">
                      </g-knob>`;

    return lemonade.element(template, self);

}

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

I am not sure why is not working for you, but take a look here. It is reacting to the button...
https://jsfiddle.net/nf6a5o8u/5/

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

This example focus on the discrepancies between function and class. It correctly sets the initial value (100) for both, because the class version contains the Object.assign() hack. But then only the function component gets updated in response to the timer... do you think there is something wrong in this code?

<html>
<script src="https://lemonadejs.net/v2/lemonade.js"></script>
<div id='root'></div>
<script>

function FunctionComponent() {
    let self = this;
    let template = `<h1>{{self.value}}</h1>`;
 
    return lemonade.element(template, self);
}

class ClassComponent extends lemonade.component {

    constructor(self) {
        super(self);
        Object.assign(this, self);
    }

    render() {
        return `<h1>{{self.value}}</h1>`;
    }

}

function MainView() {
    let self = this;

    self.value = 100;

    setInterval(() => {
        self.value++;
    }, 1000);

    let template = `<>
        <FunctionComponent value="{{self.value}}" />
        <ClassComponent value="{{self.value}}" />
    </>`;
 
    return lemonade.element(template, self, { FunctionComponent, ClassComponent });
}

lemonade.render(MainView, document.getElementById('root'));
</script>
</html>

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

Thanks, I will check that and come back to you

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

Yes, that was an issue which has been fixed. Thanks for the example.
https://jsfiddle.net/nf6a5o8u/12/

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

You don't need to use Object.assign anymore...

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

I confirm everything now works as expected, thanks.

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

By the way, is it possible to set a default state within the class implementation while retaining the ability of reading the initial state from attributes? or both things are mutually exclusive?

from lemonadejs.

hodeware avatar hodeware commented on May 9, 2024

Yes, you can overwrite the value from the initial value defined in the tag.

from lemonadejs.

lucianoiam avatar lucianoiam commented on May 9, 2024

This construct seems to work for every case, if there is a simpler/better way let me know.

    constructor(self) {
        super(self);

        this.min = self.min || 0;
        this.max = self.max || 1;
        this.value = self.value || 0.5;
    }

from lemonadejs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.