function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sivaextsivaext 

visualforce component attribute setting after onload functions

Hi,

 

 I have a page with component passing one attribute i.e.

<-- page-->

  <apex:page controller="testcontroller">

    <c:testcomponent objectname="Account"/>

  </apex:page>

   

 <-- component with controller -->

 

  <apex:component  controller="testcontroller1">

     <apex:attribute name="objectname" type="string"  description="" assignTo={!objname}/>

    <apex:dynamiccomponet componentvalue={!someList}/>

  </apex:component>

 

  public class testcontroller1  {

      public string objname {get;set;}

      public testcontroller1() {

           system.debug('............'+objname);      

     }

     public apex.componet.label getsomeList() {

           system.debug('...................'+objname);

     }

  }

 

 

problem:  objname is showing null in both places. let me know if i did anything wrong. is there is any way to get correct value for objname in any one of the place.

 

 

Bhawani SharmaBhawani Sharma
In case of component, Constructor runs first before setting up the values. So you will be only able to check the values in getter setter. Like :

public class testcontroller1 {
public string objname {
get;
set {
system.debug('Setter...................'+value);
}
}
public testcontroller1() {
system.debug('............'+objname);
}
public apex.componet.label getsomeList() {
system.debug('...................'+objname);
}
}
Shiva Ramesh @ xcdhrShiva Ramesh @ xcdhr

Hi

 

First you need to get the Account  in Page Controller which you are using to assign value to objectname after that in Component controller you need assign value like this:

 

public String objname
{
get;
set {
        if(objectname != null){
           objname = objectname;
        }
    }
}

 

bob_buzzardbob_buzzard

Your objectname will be blank in the constructor, as that runs before attribute assignment.  However, according to the Visualforce docs, it should be available by the time your getter runs:

 

--- snip ---

 

  1. The page then executes any assignTo attributes on any custom components on the page. After the assignTo methods are executed, expressions are evaluated, the action attribute on the <apex:page> component is evaluated, and all other method calls, such as getting or setting a property value, are made. 

--- snip ---

sivaextsivaext

Hi Bob,

 

 Thanks for replying, 

 

constaructor runs before assignment rules, what abot this function?

 

   public apex.component.label getsomeList() {

    system.debug('..........'+objname);

}

    when will this method executes , is it before getter & setter or after getter & setter

 

 

bob_buzzardbob_buzzard

I would expect this to be considered a getter - so that should run after the attribute assignment according to the docs

 

I'd be inclned to add some debug to the component controller and check the logs to see exactly what is going on.

doughauck-corpdoughauck-corp
Late to the party here (like 5 years late) but for any who come looking...    The answer is that by default, any getters that supply dynamic markup to an <apex:dynamicComponent> tag will be called when the parent component first loads, after the constructor but before the setters associated with the assignTo attributes.  There are two ways around this:

Method #1:  In your dynamic markup getter, use the expressions property of the Apex dynamic components instead of the value property to pass the value.  Since expressions are evaluated after the page is loaded (and assignTo setters are called), they will have access to the attribute values.

So instead of:
<apex:dynamicComponent componentValue="{!dynamicLabel}" />

public Component.Apex.OutputLabel getDynamicLabel()
{
    Component.Apex.OutputLabel outLabel = new Component.Apex.OutputLabel();
    outLabel.value = objName;
    return outLabel;
}
You would use:
<apex:dynamicComponent componentValue="{!dynamicLabel}" />

public Component.Apex.OutputLabel getDynamicLabel()
{
    Component.Apex.OutputLabel outLabel = new Component.Apex.OutputLabel();
    outLabel.expressions.value = '{!objName}';   //  <-- See the difference?
    return outLabel;
}

The resulting output markup will include the reference expressions, which will then be evaluated like any other reference expressions in your static markup, after the assignTo values have been set.  This works great for very simple applications, but one could make an argument that for anything that simple, you probably don't need dynamic markup in the first place.  What do you do when it is the value of the assignTo variable that determines how your dynamic markup is generated???

Method #2:  Use the invokeAfterAction attribute of your apex:dynamicComponent to defer the generation of the dynamic markup until after the initial page load is complete. 

<apex:dynamicComponent componentValue="{!dynamicLabel}" invokeAfterAction="false" />

public Component.Apex.OutputLabel getDynamicLabel()
{
    Component.Apex.OutputLabel outLabel = new Component.Apex.OutputLabel();
    outLabel.value = objName;
    return outLabel;
}

This is explained in the VF Developers' Guide section: Deferred Creation of Dynamic Components.  Technically, this is supposed to allow you to support generating the markup after a specific page action, but all it really does is defer generating dynamic markup until after all page actions have completed.  And since the Order of Execution - Step 3, specifies that page actions are executed after all expressions are evaluated, and since expressions require the assignTo values to be set, just setting invokeAfterAction="true" will cause your dynamic markup getter to wait until the assignTo values are set, even if you don't specify an action attribute on the page.  At least, it's worked for me so far.