0

I am running into an issue with a custom component I have written. The controller for the component has the following member:

public String crmId { get; set; }

This member is used in the component attribute as following:

<apex:attribute name="crmAccountId" assignTo="{!crmId}" ..../>

My issue is that whenever I try to change this value in the component, the setter method will always set the value to the original value that was initially assigned to it. For example, I use the member like this:

<apex:inputHidden value="{!crmId}" id="theCrmId"/>
<input type="hidden" value="{!$Component.theCrmId}" id="crmIdHook"/>

I have another javascript function that will update the HTML input tag, which should update the visualforce tag. However, the setter will never set this updated value. This issue only occurs when there is a non-null value assigned to the attribute. Any idea why?

1

That's because setters are called every time. You cannot, nor should not, rely on the assignTo value being assignable a new value at any later point in time.

Two ways I've solved this traditionally are to either enable two-way communication with the parent, or write a custom setter that uses the value only once (and usually echoed to a new variable).

The first way simply means that you don't write a hard-coded value, like so:

<c:myComponent value="abc" /> <!-- this value will keep overriding -->

Instead, use a variable:

<c:myComponent value="{!componentValue}" /> <!-- this value can be written -->
                                            <!-- back to the parent -->

The second way simply makes it write-once:

public String localCrmId { get; set; }
Boolean varSet = false;
public void setCrmId(String crmId) {
    if(!varSet && varSet = true) {
        localCrmId = crmId;
    }
}

The component itself uses localCrmId to get/set values, but the initial value will be written once by setCrmId from the assignTo attribute.

Side note: The above code uses a fairly unusual construct: an assignment inside a condition. This isn't a typo, but actually sets the value of varSet to true, and then returns true back to the condition, thus making sure that the value can only be written once per class initialization (which only occurs when there is no view state).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.