Unable to bind Component attribute with controller
Asked Answered
C

2

5

I am trying to develop a visualforce custom component which takes an attribute from a visual force page. I need to access that attribute in controller's Constructor so that i can brings some records from database and i need to display those records in the Component. But problem is that i am not getting Attribute value in Controller.

See the below code to understand the problem clearly..

Controller :

public with sharing class AdditionalQuestionController {
    public String CRFType {get;set;}
    public AdditionalQuestionController () {
        system.debug('CRFType : '+CRFType);
        List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
        system.debug('lstAddQue : '+lstAddQue);
    }
}

Component :

<apex:component controller="AdditionalQuestionController" allowDML="true">
    <apex:attribute name="CRFType" description="This is CRF Type."  type="String" required="true" assignTo="{!CRFType}" />
        <apex:repeat value="{!lstAddQue}" var="que">
            {!que}<br />
        </apex:repeat>
</apex:component>

VisualForce page :

 <apex:page >
    <c:AdditionalQuestionComponent CRFType="STE" />
</apex:page>

Thanks, Vivek

Cohune answered 19/7, 2012 at 11:12 Comment(0)
E
2

Setter methods on the attributes in a VF component appear to be called after the constructor has returned, unfortunately. Here's an alternative solution for your controller that uses a getter method to populate your list (which would be called after your CRFType member variable has been set):

public with sharing class AdditionalQuestionController {
    public String CRFType {set;}
    public AdditionalQuestionController () {
        system.debug('CRFType : '+CRFType); // this will be null in the constructor
    }
    public List<AdditoinalQuestion__c> getLstAddQue() {
        system.debug('CRFType : '+CRFType); // this will now be set
        List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
        system.debug('lstAddQue : '+lstAddQue);
        return lstAddQue;
    }
}
Earthshaking answered 19/7, 2012 at 13:4 Comment(0)
C
5

I believe the issue here is that you're expecting the member variable to have a value inside the constructor — the snag is that the instance of the class is being constructed! It doesn't exist yet and so there is no way that a non-static member variable could be given a value prior.

Instead of doing the query in your constructor, specify your own getter for lstAddQue and do the query in there when you need the data. Of course, you may want to cache the value so that the query is not run every time, but from the looks of things that won't be relevant here.

Corridor answered 19/7, 2012 at 13:6 Comment(3)
+1 for the explanation of why the setter isn't called before the constructor...I must need some more coffee.Earthshaking
I realize it's already working, but another option that's available to you (in the future) is to omit including the controller in the component and simply pass in the attribute as a type of the actual class itself. You can pass in custom Apex class instances directly into components without specifying a controller for the component. Strange - but true. It is then treated just like any other already instanced up object with all public properties and methods accessible from within the component. The constructor, however, will already have fired once in the component.Spaceport
Thanks JCD, I +1'd you as soon as I saw your answer with a code sample!Corridor
E
2

Setter methods on the attributes in a VF component appear to be called after the constructor has returned, unfortunately. Here's an alternative solution for your controller that uses a getter method to populate your list (which would be called after your CRFType member variable has been set):

public with sharing class AdditionalQuestionController {
    public String CRFType {set;}
    public AdditionalQuestionController () {
        system.debug('CRFType : '+CRFType); // this will be null in the constructor
    }
    public List<AdditoinalQuestion__c> getLstAddQue() {
        system.debug('CRFType : '+CRFType); // this will now be set
        List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
        system.debug('lstAddQue : '+lstAddQue);
        return lstAddQue;
    }
}
Earthshaking answered 19/7, 2012 at 13:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.