metarhia / swayer

Schema based frontend framework 👀
MIT License
52 stars 11 forks source link

Two-way or one-way binding in metacomponents? #12

Closed Viktor286 closed 2 years ago

Viktor286 commented 2 years ago

This topic is related to the core functionality of a framework and not clearly defined (at least to my understanding). Worst case scenarios might lead to essential bug behavior of a framework so i will ask this in form of a question but will provide bug-behavior examples.

What kind of binding direction with DOM metacomponents going to eventually have? two-way or one-way binding?

What behavior from "schema" object we expect in cases when someone would make DOM element update not via "schema setter" but somehow directly to DOM element via JS or CSS (for "styles" prop)?

lib/compiler.js image

It looks like currently in case of "independent-non-schema-update" the "schema" won't be in sync with DOM which would lead to some confused consequences.

In order to bring schema & the dom back in sync we would probably need to overwrite out-of-synced DOM values on the next schema-to-element "sync update" cycle? Not considering requesting this data from server each time, how would we do that schema-to-domElement "sync update" other than by re-assigning values we already have in schema "back to schema"?

In other words, in order to do "sync update" we should "get" data from "schema"... BUT it gives back data directly from "DOM" element which is out-of-sync ("independently-updated") at that moment.

So, by re-assigning values of "schema back to schema" we would assign values from DOM into the schema, which would makes domElemen-to-schema data flow direction (two-way binding). Would that be expected? Is it ok that we would loose original data from schema (until additional further request from server)?

image

rohiievych commented 2 years ago

We must encourage user to not manipulate DOM directly by providing convinient instruments in schema. Data binding is one way (schema-to-element) by default, but you can simply catch data changes with schema events and bind them to some state.

Viktor286 commented 2 years ago

We must encourage user to not manipulate DOM directly by providing convinient instruments in schema. Data binding is one way (schema-to-element) by default, but you can simply catch data changes with schema events and bind them to some state.

to not manipulate DOM directly -- that's understandable and totally acceptable.

But my concern was about the issue "how we bring back schema & dom into sync if they out of sync for some reason"? How about the fact that we actually have two-way binding instead of one-way binding with domElemen-to-schema data flow because of the current mechanism where the schema doesn't give its own values on "get" operation, it reflects the DOM values instead of its own. What's in the DOM will go into schema, because schema wont "get" its own values.

  Reflect.defineProperty(schema, 'styles', {
    get() {
      return element.style;
    },
rohiievych commented 2 years ago

Actually it's very expensive to reflect everything from the element into schema. It's more reasonable to reflect only schema defined data - something what is currently in use. That's why we must limit user to interact with DOM directly. If user follow this rule, there won't be any inconsistent state between schemas and DOM elements. If there is some 3rd party lib modifying DOM, it has to use metacomponent api (or adapter) or take the full responsibility about its actions. This is applicable to any framework.

There will be also a rehydration mechanizm when we come to precompiled html. Then we'll be able to create schemas from html elements like Schema.from(element) or new Schema(element). Also schema has to be garbage collected alongside its corresponding html elements to save memory.

Viktor286 commented 2 years ago

@rohiievych Thanks for your answer! Looks like a good reasoning to me. Personally, i might prefer eventually to have a more bulletproof solution but as long as it works for you that should be sufficient.

Also it sounds like a great approach to have rehydration mechanism, that should partially address the concerns i mentioned above.

Again, thanks a lot for finding a time for detailed answer! Cheers.

rohiievych commented 2 years ago

Implemented particular two-way reflection via element binding.