8

I have the following VF Component which uses a dynamicComponent tag inside of it.

<apex:component controller="myController">
<apex:attribute name="identity" 
        type="String" 
        assignTo="{!identity}" 
        description="The identity given to this component so the page can easily get access to it" />
    <apex:dynamicComponent componentValue="{!headerComponent}" />
</apex:component>

According to the VF documentation the order of evaluation inside the component is as follows:

 1. constructor methods run.
 2. attributes expressions are evaluated.
 3. executes any assignTo attributes.
 4. evaluates action method and executes all other method calls

However, I noticed that headerComponent getter will be called prior to component attribute assignments. In other words the identity string is null when I try and reference it in getheaderComponent.

This means, that I can't obtain the assigned data that is vital for rendering of my headerComponent. Is it a bug or feature?

2
  • I am experiencing the same issue. Have you found any workarounds? Thank you! Commented Jun 24, 2013 at 18:16
  • Out temporary workaround is to re-render the page after first page load. I think SF should fix this issue soon.
    – Vlad
    Commented Jun 24, 2013 at 22:18

3 Answers 3

1

Is your controller is called by passing the string following the ? in the URI of the page or is it explicitly called from within the component on the page? As you read below, I think you'll see that in either case, it doesn't appear as though it should be a problem.

For a GET Request-Create new VF page:

Constructor methods instantiating the page's controllers are called first.

Then, if a custom component is in the page, any set attribute expressions by the constructor are executed.

After the assignTo methods are executed, expressions are evaluated, the action attribute on the component is evaluated, and all other method calls, such as getting or setting a property value, are made.

If the page contains an <apex:form> component, all of the information necessary to maintain the state of the database between page requests is saved as an encrypted view state. The view state is updated whenever the page is updated.

The resulting HTML is then sent to the browser. If there are any client-side technologies on the page, such as JavaScript, the browser executes them.

*Note: Once a new get request is made by the user, the view state and controller objects are deleted.

Further, if the user is redirected to a page that uses the same controller and the same or a proper subset of controller extensions, a post back request is made. When a post back request is made, the view state is maintained.

You can find a schematic of how a page loads here.

3
  • The issue is that this doesn't appear to be following execution order in the docs. componentValue="{!headerComponent}" is being run before the assignto is evaluated. Commented Apr 17, 2013 at 16:22
  • So in-essence, it sounds like the issue is that it needs to either "re-render" after the assignment takes place or somehow refresh itself, preferably before the html is ever sent to the viewstate/browser upon initialization? Would that summarize it?
    – crmprogdev
    Commented Apr 17, 2013 at 16:37
  • Exactly. That how we have fixed this. I consider this as a temporary workaround and home SF will fix this soon.
    – Vlad
    Commented Apr 17, 2013 at 17:25
1

This problem exists indeed, but in some "simplest" cases you can workaround this using component's expressions property.

Say you have an identity property on your component's controller, accessible by VF and headerComponent property returning your dynamic component. This code will create a component with proper deferred expressions that will evaluate AFTER all attributes are set.

public ApexPages.Component getHeaderComponent(){
    Component.Apex.OutputText header = new Component.Apex.OutputText(escape = false);
    header.expressions.value = '<h2>{!identity}</h2>';
    return header;
}

Note that escape attribute of outputText is passed by value and value attribute is passed via expression that evaluates some time later.

The point why we can consider this case as "simplest" is that you have here fixed, static structure of dynamic component. That is, component tree is always the same - you have an <apex:outputText/> and nothing more. In truly dynamic case when component structure should be formed based on your data - dynamic components fail on the first run.

@Vlad says right, rerender trick initializes the attributes and turns your component alive (usually).

0

I think if you follow the pattern of lazily initializing your bind variables in their corresponding get methods, you can be assured that the assignTo variable has been assigned at that point.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .