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

stateFn for #each loop #16

Open
christianvoigt opened this issue Mar 21, 2015 · 6 comments
Open

stateFn for #each loop #16

christianvoigt opened this issue Mar 21, 2015 · 6 comments

Comments

@christianvoigt
Copy link

Hi, I migrated the templates of my app to FlowComponents and overall this worked out great and improved my code a lot. However, in some cases I have lost the fine-grained reactivity I had before. These cases follow all the same pattern:

{{#each state$myArray}}
{{>render component="my-component" myProperty=this}}
{{/each}}

If I understand this right, I need to use stateFn$ to wrap the value of myProperty in a function, to avoid rerenderings if myProperty changes. But how can I do this in these cases, where stateFn$myProperty can not be used? Another case in which this problem occurs is something like:

{{>render component="my-component" myProperty=state$myObj.myProperty}}
@arunoda
Copy link
Member

arunoda commented Mar 21, 2015

stateFn for this may not work. I need to think some way to do it.

You should not use . operator for states. They will cause re-rendering. This is not only for flow-components. But for templates in general.

@christianvoigt
Copy link
Author

Hi, as this issue is really vital for my project I created a small example to examine the rerendering behavior of simple blaze templates compared to flow components. Please excuse the rather long message.

  • First of all, the example shows that the . operator does not cause rerendering in general.
  • Secondly, I discovered some interesting differences between the handling of live queries and their fetched results.

You can find the source code here: https://github.com/christianvoigt/flow-components-rerendering-test
I have deployed the example here: http://flow-components-rerendering-test.meteor.com/

I have created a local collection called Greetings and inserted some initial greetings of the form {text:String} that are displayed in two #each loops. The first uses a normal template that has the attribute greetingText=this.text. The second loop uses a flow component with the same attribute.

Please open the console to get log messages about how many "greeting templates" and "greeting components" were created, rendered and destroyed. If you click on the first link that inserts a new document into the collection, you will see that only one new template is created and rendered, while all flow components are destroyed, recreated and rerendered. This is the problem we already talked about. Interestingly, this problem only occured if I used Greetings.find().fetch() instead of Greetings.find() for the #each loops.

So one option would be to only use live queries in these cases. But this is very limiting. I thought maybe it would be possible to wrap this.text in the #each loop into a function similar to what stateFn$ does, but that doesn't seem to work either.

If you click on the second link, the text of one document in the collection will be updated. As I already said above, this does not cause a rerendering of any of the normal templates, even though I used the . operator. But it does cause a complete rerendering of the list of components.

Do you have any ideas for a workaround I could implement on my own? If I can't get this to behave in the same fine-grained way as it did before, I fear I have to revert to simple Blaze templates for now.

@rolfnl
Copy link

rolfnl commented Mar 30, 2015

Yes, I have the same question sort of...

Can you perhaps show an example when you use parent + child components looping over a collection and what the default/expected behavior is when you update the cursor/document or any reactive var/state in the component.

@rclai
Copy link

rclai commented Mar 31, 2015

@arunoda If we shouldn't pass . into the child component, how should we pass it in order for it to be more efficient?

@pward123
Copy link

pward123 commented Jun 3, 2015

+1

@bitomule
Copy link

I have this issue too of components inside #each loops always rendering on changes. Any idea on how to fix it?

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

6 participants