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

Should the children in a loop inherit the parent mixins? #896

Closed
GianlucaGuarini opened this issue Jun 30, 2015 · 31 comments
Closed

Should the children in a loop inherit the parent mixins? #896

GianlucaGuarini opened this issue Jun 30, 2015 · 31 comments

Comments

@GianlucaGuarini
Copy link
Member

Current riot (note translate is a mixin assigned to my-tag )

<my-tag>
  <ul>
    <li each={ item in items }>{ parent.translate(item) }</li>
  </ul>
</my-tag>

My proposal ( the li tags will inherit the parent mixins if they will not have them already defined )

<my-tag>
  <ul>
    <li each={ item in items }>{ translate(item) }</li>
  </ul>
</my-tag>
@cognitom
Copy link
Member

👍 for no parent.
But it seems that it breaks the scope model...

@cognitom
Copy link
Member

Hmmm, sorry, after some thoughts, I don't think so now.
We need a simpler way to access the method like translate() or filter() in the expression without messy parent. But I'm not sure we should connect it to mixin feature.

How about @ syntax? I mean that @ is the shortcut of parent.parent... and always point the root scope of the tag.

<my-tag>
  <ul>
    <li each={ item in items }>{ @translate(item) }</li>
  </ul>
</my-tag>

@rsbondi
Copy link
Contributor

rsbondi commented Jun 30, 2015

Brilliant suggestion @cognitom the top level tag scope could be passed to all children. I am not sure that @ would be conflict free? I know coffescript would translate to js so probably not a conflict, but it may be confusing. I think maybe top.translate() or something.

@GianlucaGuarini
Copy link
Member Author

I would simply inherit all the parent properties to the children. If a child has a property named like the one in the parent it will not be overridden..it seems simple to implement and easy to understand. This will neither be a breaking change

@cognitom
Copy link
Member

@rsbondi Good point! A down side of @ is that it's not a part of JavaScript. top. seems cleaner.

inherit all the parent properties

@GianlucaGuarini It seems convenient. Actually, I chose that option for riot-bootstrap. But it was kind of "emergency avoidance". I'm wondering from the aspect of memory. If the tag has an array with 100 elements, 100 x 100 items will be made for the children...

@GianlucaGuarini
Copy link
Member Author

@cognitom javascript will pass only the reference to the object, it will not clone it, so the memory should not be a problem

@cognitom
Copy link
Member

If these are the primitive types (String, Number, etc.), the objects will be cloned. But I agreed that we use an array as a collection (of objects) in tag definition basically. So I hope that's not the problem.

UPDATE: sorry, my understanding was wrong. Premitive types is immutable and passed by reference. so we don't have to worry about it at all, as @GianlucaGuarini said.

@cognitom
Copy link
Member

Is that possible to tweak this line to include the all parent scopes?
https://github.com/riot/riot/blob/master/lib/browser/tmpl.js#L195

If so, children don't have to have inherited properties. It makes some sense for me because I can't imagine the use case from the constructor. How about..?

<my-tag>
  <child-tag>{ translate(item) }</child-tag> // good!
  this.mixin('i18n')
</my-tag>
<child-tag>
  <p><yield /></p>
  var str = this.translate('something') // bad?: the inherited property seems confusable
</child-tag>

Anyway, it's interesting discussion. 😄

@cfenzo
Copy link
Contributor

cfenzo commented Jul 2, 2015

But isn't this two different things? "Child tag" vs "loop child"? Or am I missing something in how riot handles loops and tags...?

I don't find it naturally that a child tag should inherit the properties of a parent tag, it could lead to some strange cases of "guess the scope", and would easily lead to tight coupling between tags and thus non-reusable tags.

But inside a loop (loop child) it would make a lot of sense to inherit the parent properties, or have them available with top. or @ prefix. When you have multiple nested loops (sigh), keeping track of the nesting levels to access properties of the tag is cumbersome and error-prone. 👍

@r4j4h
Copy link
Contributor

r4j4h commented Jul 2, 2015

@cfenzo Thank you for the clarification. My fear with the anti-.parent sentiment is that we would lose just that with the "child tags". I never want to end up having to "guess the scope" - that's part of where Riot makes things nice. :)

I like the idea of .top. That implies it always goes to the outer loop though, not some interim property merging thing for any level of nested loop. Perhaps .loopscope? I can't think of a good semantic meaning behind @ for this purpose though.

And as an aside just to make it mentioned: I want to ease the mental overhead of tracking nesting loop levels, but I don't want us to lose the ability to explicitly use the loop stack if we want using .parent

@rsbondi
Copy link
Contributor

rsbondi commented Jul 2, 2015

after this line

this.top = this.parent ? this.parent.top : this

seems simple enough for the top option, easier than inheriting all properties

example

@cognitom
Copy link
Member

cognitom commented Jul 2, 2015

@rsbondi, how about this case?

<app>
  <my-tag />
</app>
<my-tag>
  <child-tag>{ top.translate(top.titile1) }</child-tag>
  this.mixin('translate')
  this.title1 = 'Hello'
</my-tag>
<child-tag>
  <span><yield /></span>
</child-tag>

top.translate() inside the <child-tag> won't work because in this case top points to <app>. In my original thought, I assumed @ pointed to the top in definition (not the most outside tag). I think it should not depend on the tags outside. But I realised that it could be ambiguous for users...

We have two options now, and both have pros and cons. I hope there is a third option, it has not come to mind yet...

  • inherit all parent's property
  • reference tag root by top.

@cfenzo I agreed your concern about inherit. I think in addition "Child tag" and "Transcluded tag" should be different thing, too. cf. #856

@rsbondi
Copy link
Contributor

rsbondi commented Jul 3, 2015

inherit properties version

In tag.mount, not sure if it is in the best place

if(self.parent)
  each(Object.keys(self.parent), function(k) {
    if(!self[k]) self[k] = self.parent[k] 
  })

@GianlucaGuarini
Copy link
Member Author

I have added the possibility to inherit all the parent properties for all the children tags in a loop! Riot will keep in sync only the child undefined properties avoiding to override things that should not be overridden by the parent tag.

GianlucaGuarini added a commit that referenced this issue Jul 5, 2015
@GianlucaGuarini
Copy link
Member Author

@tipiirai I have released riot 2.2.2-beta, we need to update the documentation describing that now in a loop the parent properties will be inherited by the children (see above). Please do not update the site until the documentation is complete. I will update the documentation during the next week.

r4j4h added a commit to r4j4h/riot that referenced this issue Jul 6, 2015
WIP: Update documentation to reflect parent property-in-loop changes in riot 2.2.2-beta

To aid in riot#896
@r4j4h
Copy link
Contributor

r4j4h commented Jul 6, 2015

@GianlucaGuarini I hope I am not stepping on your toes but I took a stab at starting to update the documentation.

@GianlucaGuarini
Copy link
Member Author

@r4j4h thanks well done! Are we sure this is the only part in the doc we need to update?

@r4j4h
Copy link
Contributor

r4j4h commented Jul 6, 2015

Not entirely sure, I glanced through to find different examples or mentions of each but couldn't find any better places that were actually illustrating nesting loops. Perhaps we should add an example somewhere?

This is the closest other thing I could find.

@andynemzek
Copy link
Contributor

@GianlucaGuarini @r4j4h This one bit me hard...sunk a bit of time into it. Think there's two problems here:

  1. I don't think https://muut.com/riotjs/guide/#context is describing the current functionality. It states that parent still needs to be used in the loop which does not appear to be the case in that example. The loop can access the parent's functions/variables without the use of parent.

  2. Though the parent properties are shared with the looped items, the opts variable is not. If this is intended, it should be well documented...it's not obvious. This is where I burned a lot of time...trying to figure out why I couldn't access my data in opts while in a loop. In that case I did need to use parent.opts.

@deakster
Copy link

This doesn't seem to work with transclusion, which makes things even more confusing. For example:

<my-tag>
  <ul>
    <li each={ item in items }>
      <span>{ testy } - This works</span>
      <my-custom-tag>{ testy } - Transcluded, this doesn't work</my-custom-tag>
    </li>
  </ul>

   <script> this.testy = "hello"; </script>
</my-tag>

Because of that and point 2) mentioned by @andynemzek, I went back to just using parent. everywhere, otherwise the code ends up looking completely inconsistent and confusing.

@cognitom
Copy link
Member

@deakster I agreed.
I hope that the scope and the properties of the tag are separated properly, too. Hmm... but how can we implement it simply. Need to look into the code.

@nippur72
Copy link
Contributor

nippur72 commented Aug 3, 2015

If I can add my .2$, I am against inheriting properties from parent, when you debug it's an hell, you get lot of name clashes and it's hard to recognize even what your this is.

@tipiirai
Copy link
Contributor

tipiirai commented Aug 4, 2015

I definitely like this feature, but do we still support the .parent @GianlucaGuarini? I'm sure there are many people who still prefer to be explicit.

@GianlucaGuarini
Copy link
Member Author

@tipiirai yes you are right, we support both, but the child tags in a loop inherit all the parent properties ( except the properties in our blacklist )

@GianlucaGuarini
Copy link
Member Author

@tipiirai implementing the tag.rel property for the named elements it will be everything a bit nicer, we could do it in riot 2.3

@avimar
Copy link

avimar commented Jan 14, 2016

Now that I updated to 2.3, I see that my "success" messages get propogated to any child tags, and there didn't seem to be any way to avoid that.
Can you explain the final implementation better?

@5angel
Copy link
Contributor

5angel commented Jul 14, 2016

I'm still waiting for a solution for a parent's bandwagon problem, i.e. getting to the root tag from multiple transclusions requires use of "parent.parent.parent.parent".

Angular solved this by making children inherit all named variables from parent scope. Can we do something like this?

@GianlucaGuarini
Copy link
Member Author

@5angel

multiple transclustions...

I am sure you are doing it just doing it in the wrong way.. Probably you should just switch to angular if it suits better your needs. Please post a valid example opening a new issue so we can check where is the problem

@5angel
Copy link
Contributor

5angel commented Jul 14, 2016

@GianlucaGuarini nah, i like riot for it's simplicity, but there are some things that are bothering me.

For tranclusions, I mean stacking tags like this:
<my-tag> <my-popover> <my-slider></my-slider> <my-input></my-input> </popover> </my-tag>

This way, it becomes hard to access ddata from input, for example. So is there a tip somewhere explaining the right way?

@GianlucaGuarini
Copy link
Member Author

Maybe this could help you structuring your core https://github.com/GianlucaGuarini/riot-app-example

@avimar
Copy link

avimar commented Jul 15, 2016

@5angel or use a flux pattern, such as with https://github.com/jimsparkman/RiotControl/ https://github.com/luisvinicius167/Riotux/

EDIT: that example uses something similar.

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

No branches or pull requests