-
Notifications
You must be signed in to change notification settings - Fork 26
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
Provide equivalents to Blaze.render, Blaze.renderWithData and Blaze.remove #36
Comments
In the meantime, can you help me out with this example:
In that code, I want to animate IN the panel that is being created. I know about the insertDomElement, but I don't want to use that route, since the code I need to animate is inside the component class of the panel. So getting to the question, how can I get a reference to the component instance of the "comp" I just created? If I try it after BlazeComponent.getComponent(name); I get a Class back (not the instance). If I try it after renderComponent() I get a Blaze.Template back. If I try it after renderWithData() I get a Blaze.View back. Is what I'm trying even possible? Views...Templates...Instances...Components...oh my :) Tnx. |
You can do:
|
Got it, tnx! Does components change anything in the lifecycle of that view? I need to wait for that view to be rendered on screen before talking to it. In my old version of mentioned stack, i used "view.onViewReady()" for that. If I use that in this example, it's not called. Or am I missing something.
P.S. I tried listening to the comp instead of to the view. But there is no equal method for components right? I can't call say
Can I? |
I do not get you? You have class MyComponent extends BlazeComponent
@register 'MyComponent'
template: ->
'MyComponent'
onRendered: ->
console.log 'I am never called'
@callFirstWith null, 'doAnything' ViewStackComponent = BlazeComponent.extendComponent({
add: function (name) {
var comp = new (BlazeComponent.getComponent(name))();
var renderedComponent = comp.renderComponent(this);
var view = Blaze.renderWithData(comp, data, this.firstNode());
}
}); |
Alternatively, you can also do: ViewStackComponent = BlazeComponent.extendComponent({
add: function (name) {
var comp = new (BlazeComponent.getComponent(name))();
var renderedComponent = comp.renderComponent(this);
var view = Blaze.renderWithData(comp, data, this.firstNode());
this.autorun(function (computation) {
return unless comp.isRendered();
computation.stop()
console.log('Do this as well when rendered');
});
}
}); |
That last one did the trick. Thanks! Food for thought, maybe match the Blaze api for this regarding "extending" onRendered callbacks like:
But maybe that's just a nice to have :) |
No. This is not reusable nor composable. You should put hooks into the class method, so that you can reuse it in your children implementations. If you attach hooks like Blaze does, then you have issues when you want to reuse those hooks. You have to copy them. And you have to manually decide how to override/extend them. Reactive In your case, I would suggest you just use the first approach. Class method |
Well, it's just a matter of seperation of concerns (kind of). My parent lays out it's children (simply saying). The parent is the only one that should know of all it's children and I want it to be able to tell each child where to go. When a child is added, I want the parent to be able to tell it "you need to go to this position". But telling it to that child can only be done once it's rendered. So I was stuck :) But the workaround works, it just feels a bit verbose. I'm not sure if I understand how that would make it less composable either. But will try to read it again later, just in case ;) |
Which workaround? My snippets above are not workaround, but normal code. :-)
Hooks would make it less composable. This is why we do not provide them. :-)
But why don't you create an explicit API for this? class ChildComponent
...
onRendered: ->
@componentParent().tellMeWhereToGo() You could also do something like this in the parent: listOfRenderedChildren = []
@autorun =>
newListOfRenderedChildren = (child for child in @componentChildren() when child.isRendered())
for child in newListOfRenderedChildren when child not in listOfRenderedChildren
child.iAmTellingYouWhereToGo()
for child in listOfRenderedChildren when child not in newListOfRenderedChildren
@myChildHasBeenRemoved child
listOfRenderedChildren = newListOfRenderedChildren |
You're right, not a workaround. It's just different related to Blaze, which is fine. But for me as a noob, it's intimidating :) Might be for others as well.
Because that's a hard link between the child and the parent. It must be my old school thinking, but to me that seemed inappropriate since it's possible that the child is used without the wrapping parent. Then it call's a function that won't exist? I'm using the autorun example now, works great. |
But when it is used with the wrapping parent, how does the wrapping parent interact with the component? Make that into an explicit API and this is it. Or calling it from the child, or calling it from the parent. |
True, exactly what I was trying to do. But had a hard part with waiting for the child component to be rendered (because the explicit API I'm calling from the parent to the child, needs that child's DOM). |
Quick note, currently when you use Blaze.remove and directy after that call something that (e.g.) loops through this.componentChildren(), I'm getting weird errors about DOM not being available. This might be related to the package dispatch:kernel I use though. |
Make a reproduction please. |
TL;DR I think this works. It must be something else, hidden within one of the packages or animations I use. Will dig deeper to find out the exact cause of the DOM exception, but in this http://meteorpad.com/pad/fiBufg8EQiyPJX8r9/Remove%20then%20loop example it works. |
Instead of |
Provide equivalents to
Blaze.render
,Blaze.renderWithData
andBlaze.remove
.For now you can use for
Blaze.render
:or
For
renderWithData
:And
Blaze.remove
:The text was updated successfully, but these errors were encountered: