jarek-foksa / xel

Xel - Widget toolkit for building native-like Electron and Web apps
https://xel-toolkit.org
Other
682 stars 59 forks source link

AngularJS – bind-value-to="" not propagated? #37

Closed sandor closed 3 years ago

sandor commented 6 years ago

Not sure what's going on there. We had the problem with the "x-numberinput" not working with the bind-value-to in AngularJS. Now the "x-numberinput" is working perfectly but other elements like "x-radio" etc. will not accept the two way binding of AngularJS.

This is working in my code:

        <x-box>
            <label>
                Left
                <input type="radio" name="origin-x" class="origin-x btn-object-action" value="left" bind-value-to="originX">
            </label>
            <label>
                Center
                <input type="radio" name="origin-x" class="origin-x btn-object-action" value="center" bind-value-to="originX">
            </label>
            <label>
                Right
                <input type="radio" name="origin-x" class="origin-x btn-object-action" value="right" bind-value-to="originX">
            </label>
        </x-box>

This one is not working:

        <x-radios>
            <x-box>
                <x-radio id="first-radio" toggled value="left" bind-value-to="originX"></x-radio>
                <x-label for="first-radio" id="label-1">Left</x-label>
            </x-box>
            <x-box>
                <x-radio id="second-radio" value="center" bind-value-to="originX"></x-radio>
                <x-label for="second-radio" id="label-2">Center</x-label>
            </x-box>
            <x-box>
                <x-radio id="third-radio" value="right" bind-value-to="originX"></x-radio>
                <x-label for="third-radio" id="label-3">Right</x-label>
            </x-box>
        </x-radios>

Trying to get the function with some Button fail also:

        <x-buttons tracking="1">
            <x-button toggled ng-value="left" bind-value-to="originX" ng-model="originX" click="setActiveProp('originX', left);">
                <x-label>Left</x-label>
            </x-button>

            <x-button ng-value="center" bind-value-to="originX" ng-model="originX" ng-model="originX" click="setActiveProp('originX', center);">
                <x-label>Center</x-label>
            </x-button>

            <x-button ng-value="right" bind-value-to="originX" ng-model="originX" ng-model="originX" click="setActiveProp('originX', right);">
                <x-label>Right</x-label>
            </x-button>
        </x-buttons>

Any clue?

BTW: the new release is cool. I really love your work. Thank you for your efforts. I wish I could be able to contribute more. But at least I will try to give you a UseCcase (getting better and better, but takes time).

https://github.com/sandor/floido-designer

:-)

Question: Why did you abandoned the galaxy style – not that I would need it but it was pretty nice?

Anyhow: as a suggestion, you should make the latest build available for linking on codepen/fiddle etc. – at least as a "built" as gitraw, so that we can reproduce problems?

jarek-foksa commented 6 years ago

I didn't make any significant changes to <x-numberinput> and <x-radios> since you reported the issue for the first time. I just migrated the code to ES6 modules and added a simple getter/setter here.

I'm not sure what is causing your issues, but one guess is that you (either directly or via Angular) might be setting JS properties on custom elements that have not been defined yet. For example, you will permanently mess up a Xel button when you execute button.value = 10; while <x-button> custom element is not defined.

To ensure all elements in the current document are defined, you could use following code:

Promise.all([...document.querySelectorAll(":not(:defined)")].map($0 => customElements.whenDefined($0.localName))).then(() => {
  // Code that manipulates custom elements goes here
});

BTW: the new release is cool. I really love your work. Thank you for your efforts. I wish I could be able > to contribute more. But at least I will try to give you a UseCcase (getting better and better, but takes > time).

https://github.com/sandor/floido-designer

Thanks, the Floido Designer app looks interesting. I think I should add "Showcase" tab to xel-toolkit.org site which would list projects like that. Please let me know if you know of any other apps using Xel.

Question: Why did you abandoned the galaxy style – not that I would need it but it was pretty nice?

I have removed the Galaxy theme for now because it felt unfinished and I'm not using it in any of my current projects. I definitely won't be removing the other existing themes.

Anyhow: as a suggestion, you should make the latest build available for linking on codepen/fiddle etc. – at least as a "built" as gitraw, so that we can reproduce problems?

Yeah, I will give it a try later this month.

sandor commented 6 years ago

Hey, I have done a few test here, since I have to use a lot of those radios and stuff. I have no clue what is going on here. Just made the following observations.

This is my function that waiting for a value:

    $scope.getOriginX = function () {
        return getActiveProp('originX');
    };

    $scope.setOriginX = function (value) {
        setActiveProp('originX', value);
    };
is working fine. I am using it like this as a test: `

` In addition to the x-radio I have also tried with selects. This is working:

    <select bind-value-to="originX">
        <option ng-value="left">
            left
        </option>
        <option ng-value="center">
            center
        </option>
        <option ng-value="right">
            right
        </option>
    </select>

This is not working:

        <x-select>
            <x-menu bind-value-to="originX">
                <x-menuitem ng-value="left" selected="true">
                    <x-label>Left</x-label>
                </x-menuitem>

                <x-menuitem ng-value="center">
                    <x-label>Center</x-label>
                </x-menuitem>

                <x-menuitem ng-value="right">
                    <x-label>Right</x-label>
                </x-menuitem>

            </x-menu>
        </x-select>

Using value instead of ng-value is working:

        <x-select bind-value-to="originX">
            <x-menu>
                <x-menuitem value="left" selected="true">
                    <x-label>Left</x-label>
                </x-menuitem>

                <x-menuitem value="center">
                    <x-label>Center</x-label>
                </x-menuitem>

                <x-menuitem value="right">
                    <x-label>Right</x-label>
                </x-menuitem>

            </x-menu>
        </x-select>

This is still not working:

        <x-radios bind-value-to="originX">
            <x-box>
                <x-radio id="first-radio" toggled value="left"></x-radio>
                <x-label for="first-radio" id="label-1">Left</x-label>
            </x-box>
            <x-box>
                <x-radio id="second-radio" value="center"></x-radio>
                <x-label for="second-radio" id="label-2">Center</x-label>
            </x-box>
            <x-box>
                <x-radio id="third-radio" value="right"></x-radio>
                <x-label for="third-radio" id="label-3">Right</x-label>
            </x-box>
            <x-radios>

This should be the way how it is declared with native radios, so this should be working:

        <x-radios>
            <x-box>
                <x-radio id="first-radio" toggled value="left" bind-value-to="originX"></x-radio>
                <x-label for="first-radio" id="label-1">Left</x-label>
            </x-box>
            <x-box>
                <x-radio id="second-radio" value="center" bind-value-to="originX"></x-radio>
                <x-label for="second-radio" id="label-2">Center</x-label>
            </x-box>
            <x-box>
                <x-radio id="third-radio" value="right" bind-value-to="originX"></x-radio>
                <x-label for="third-radio" id="label-3">Right</x-label>
            </x-box>
            <x-radios>

The same is with the x-checkbox. The native checkbox is working, the x-checkbox not:

<x-checkbox ng-true-value="center" ng-false-value="right" bind-value-to="originX"></x-checkbox>

<input type="checkbox" ng-true-value="center" ng-false-value="right" bind-value-to="originX">

I have really no clue what is wrong there, since the function needs only the "value" from the radio (same like in the x-input).

Thanks for the code snippet you provided, but (sorry for my ignorance) – I have really not the knowledge where and how to use it...

If you don't have an idea what's going on there, I will try to get some help on StackOverflow. I am simply need those radios :-)

I have found also some good explanations about the Angular JS ng-value, not sure if this helps:

https://stackoverflow.com/questions/28717523/whats-the-difference-between-ng-model-and-ng-value

jarek-foksa commented 6 years ago

I can see a lot of framework-specific stuff there, so I have no idea what is causing this issue.

Thanks for the code snippet you provided, but (sorry for my ignorance) – I have really not the knowledge where and how to use it...

When building a client-side web app, you usually wait for the the document to fully load before you start manipulating it by using document.addEventListener("load", () => { /* your code goes here */ });. I meant that you should use similar approach to also ensure that all custom elements are defined. Again, I have no idea how this is relevant in context of Angular.

jarek-foksa commented 3 years ago

Xel project underwent a major rewrite recently. If you can still reproduce this bug, please report it on https://xel-toolkit.org/issues.