Невозможно связать атрибут компонента с контроллером

Я пытаюсь разработать пользовательский компонент visualforce, который берет атрибут со страницы визуальной силы. Мне нужно получить доступ к этому атрибуту в конструкторе контроллера, чтобы я мог принести некоторые записи из базы данных, и мне нужно отобразить эти записи в компоненте. Но проблема в том, что я не получаю значение атрибута в контроллере.

См. приведенный ниже код, чтобы четко понять проблему.

Контроллер:

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);
    }
}

Компонент :

<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:

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

Спасибо, Вивек


person Vivek    schedule 19.07.2012    source источник


Ответы (2)


Методы установки для атрибутов в компоненте VF, к сожалению, вызываются после возврата конструктора. Вот альтернативное решение для вашего контроллера, которое использует метод получения для заполнения вашего списка (который будет вызываться после того, как ваша переменная-член CRFType была установлена):

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;
    }
}
person JCD    schedule 19.07.2012

Я полагаю, что проблема здесь в том, что вы ожидаете, что переменная-член будет иметь значение внутри конструктора — загвоздка в том, что создается экземпляр класса! Он еще не существует, поэтому нет возможности, чтобы нестатическая переменная-член могла получить значение раньше.

Вместо выполнения запроса в конструкторе укажите собственный геттер для lstAddQue и выполните запрос там, когда вам понадобятся данные. Конечно, вы можете захотеть кэшировать значение, чтобы запрос выполнялся не каждый раз, а исходя из того, что здесь не будет иметь значения.

person Matt Lacey    schedule 19.07.2012
comment
+1 за объяснение, почему сеттер не вызывается перед конструктором... Мне нужно еще немного кофе. - person JCD; 19.07.2012
comment
Я понимаю, что это уже работает, но другой вариант, доступный вам (в будущем), состоит в том, чтобы не включать контроллер в компонент и просто передать атрибут как тип самого фактического класса. Вы можете передавать пользовательские экземпляры класса Apex непосредственно в компоненты, не указывая контроллер для компонента. Удивительно, но факт. Затем он обрабатывается так же, как любой другой уже созданный экземпляр объекта со всеми общедоступными свойствами и методами, доступными из компонента. Однако конструктор уже один раз запустился в компоненте. - person Adam; 19.07.2012
comment
Спасибо, JCD, я поставил вам +1, как только увидел ваш ответ с образцом кода! - person Matt Lacey; 20.07.2012