Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Understanding x-data as a component #100

Closed
stuartpullinger opened this issue Jan 17, 2020 · 6 comments
Closed

Understanding x-data as a component #100

stuartpullinger opened this issue Jan 17, 2020 · 6 comments

Comments

@stuartpullinger
Copy link

I find the name 'Component' for the element with the x-data attribute a little confusing. It doesn't fit with my mental model of what a component is. Based on other frameworks (React/Vue etc), I think of a component as a class or function, data/state like instance/local variables and props as arguments to a constructor/function. In this way, I think of a component as providing encapsulation and reusability.

In the case of Alpine, I am not sure the x-data component models the same concepts. The reusability is provided by server-side template partials or some other method chosen by the user. The x-data component provides encapsulation as it is - but the nested scopes discussed in #49 would break that. Nested scopes without some other form of encapsulation/barrier feels like dynamic scoping - unfamiliar territory.

So, reusing an example from #49, the api which fits my mental model would look more like this:

<div x-component="{foo: surrounding.scope.thefoo}">     <!-- Barrier to further scope nesting.   -->
                                                        <!-- Evaluated in the surrounding scope. -->
                                                        <!-- Would 'foo' need to be quoted?      -->
  <div x-data="{}">
    <div x-data="{}">
        <button x-on:click="foo = ''bob"></span>
        <span x-text="foo"></span> <!-- bob -->
    </div>
    <span x-text="foo"></span> <!-- foo provided in 'prop' -->
  </div>
</div>

(In this case, I imagine an x-component attribute without a value - a boolean attribute - would just provide the encapsulation/barrier without defining any props.)

I know that recreating all of Vue is a non-goal of this library (and I applaud that) so maybe this is overkill. Please let me know if/how I should adjust my mental model. I'm happy to contribute to documentation.

@SimoTod
Copy link
Collaborator

SimoTod commented Jan 17, 2020

It's a fair point but aren't you adding an unnecessary div only to fit a mental model in that way?

Regarding the nested scopes, the way they will work still need to be defined, it could be a prop approach (Vue-like) rather than a free access to the parent scope.

@stuartpullinger
Copy link
Author

I added the extra div for clarity, I suppose - couldn't it work without it? Like this:

<div x-component="{foo: surrounding.scope.thefoo}" x-data="{}">
    <div x-data="{}">
        <button x-on:click="foo = ''bob"></span>
        <span x-text="foo"></span> <!-- bob -->
    </div>
    <span x-text="foo"></span> <!-- foo provided in 'prop' -->
</div>

I like the nested scope proposal - provided there is a safety barrier 🚧 !

@SimoTod
Copy link
Collaborator

SimoTod commented Jan 17, 2020

Would it apply to normal elements? Would it be required or optional?

Right now, the snippet below works correctly.

<script>var foo = 'bar' ;</script>
<div x-data={}>
<span x-text="foo"></span> <!-- // bar -->
</div>

@stuartpullinger
Copy link
Author

stuartpullinger commented Jan 17, 2020

I'm not sure that I understand the questions but... It could apply to any element, I think, but entirely optional. Here's a rather convoluted example of how I would imagine the scope working. With x-data implementing nested scope, the x-component essentially works how x-data does in your example above - anything not found so far is looked for in the global scope, skipping over intermediate x-datas.

<script>
  var foo = 'globalfoo' ;
  var bar = 'globalbar' ;
  var baz = 'globalbaz' ;
</script>
<span x-text="`${foo} ${bar} ${baz}`"></span>    <!-- globalfoo globalbar globalbaz -->

<div x-data="{foo: 'outerfoo', bar: 'outerbar', baz: 'outerbaz'}">
  <span x-text="`${foo} ${bar} ${baz}`"></span>    <!-- outerfoo outerbar outerbaz -->

  <div x-component="{foo: 'propfoo', bar: bar}">     <!-- No baz defined here-->
                                                     <!-- outer bar passed in -->
    <div x-data="{bar: 'innerbar'}">
        <button x-on:click="foo = ''bob"></span>
        <span x-text="`${foo} ${bar} ${baz}`"></span> <!-- bob innerbar globalbaz-->
                                                      <!-- baz comes from the global scope -->
    </div>
    <span x-text="`${foo} ${bar} ${baz}`"></span>    <!-- propfoo outerbar globalbaz -->
  </div>

  <span x-text="`${foo} ${bar} ${baz}`"></span>    <!-- outerfoo outerbar outerbaz -->
</div>

<span x-text="`${foo} ${bar} ${baz}`"></span>    <!-- globalfoo globalbar globalbaz -->

@SimoTod
Copy link
Collaborator

SimoTod commented Jan 17, 2020

Sorry, I didn't want to criticize your proposal, I was just trying to understand it better.
I'm not sure it would work for everybody though. A simple inherited context model (As javascript does with blocks) seems easier to describe and understand to me, but I appreciate that what may work for one it won't necessary work for other ones. It seems that this implementation is in the pipeline so we'll find out soon, I guess.

@stuartpullinger
Copy link
Author

It's OK - I didn't infer any criticism. Thanks for taking the time to consider my idea. I genuinely didn't think I understood your questions. 'Guess I need to use more emojis in my text so my intentions are clear 😀 .

Thanks 👍 👏 I really appreciate your work on this library and I am eager to follow how it develops - particularly x-for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants