I am working on a project right now and I just noticed something, that makes sense, but I did not realize it.
The Visualforce page and the Visualforce component both use the same controller. Now correct me if I am wrong, but when the Visualforce component is called from the Visualforce page, the component will then instantiate the controller again and have its own instance of the controller.
This is essentially doubling the amount of SOQL depending on the code used (if you have many SOQL in the constructor). If what I am saying is correct, could you see a way to pass in a pointer to the component, from the page, that will indicate to use the already instantiated controller? I do not believe something like this is possible currently, but that is my thought on how it could be done in future instances if they were to make this possible.
I noticed this when I called a component from repeat in the visualforce page, and then I called a component from repeat in the previously created component. I had 5 SOQLs in my constructor, and this led to me hitting the SOQL limit on page load. I believe this was due to the 2nd component being called so much and doing the 5 SOQLs over and over again.
I'm looking for clarification to see if what I am saying is correct in this matter.
2 Answers
Yes, you are right. All the visualforce components and page loaded in a single apex transaction. An Apex transaction represents a set of operations that are executed as a single unit. All DML operations in a transaction either complete successfully, or if an error occurs in one operation, the entire transaction is rolled back and no data is committed to the database.
As Badan said, you are correct. So, what we do to share a large amount of data from the page to the component is: 1) Build a data class containing objects and values you want both items to share. 2) After populating an instance the data class in the page controller or extension constructor, pass it to the component as an attribute.
Value changes in the component will be reflected in the page controller and visa versa.
You can also use the data class as a base class using the "extends" keyword.