2

I hope many of you have faced this issue already. So, interested in knowing the root cause of the problem.

Page:

<apex:page>
    <apex:form>
        <c:sanTestComp2 defaultText="Default Text Input"/>
    </apex:form>
</apex:page>

Component

<apex:component controller="sanTestCtrl1">
    <apex:attribute name="defaultText" type="String" Description="Default Text" assignTo="{!inpText}"/>
    <apex:pageMessages id="infoMessage"/>
    <apex:pageBlock>
        <apex:pageBlockbuttons>
            <apex:commandbutton value="save" action="{!save}" rerender="infoMessage"></apex:commandbutton>
        </apex:pageBlockbuttons>
        <apex:pageblocksection>
            <apex:inputText label="Enter Some Text" value="{!inpText}"/>
        </apex:pageblocksection>                  
    </apex:pageBlock>
</apex:component>

Controller

public class sanTestCtrl1 {
    Public String inpText{get;set;}

    public void save(){
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Value of Text is-'+inpText));
    }
}

When i type some text & hit save, you normally would expect the typed in string to dispaly in ApexMesssage. But, I get the default text. I'm sure if you change string to object wrapper type, it will work. But, that will be too much for such a simple example. So, not interested with any workarounds.

can someone answer with real reason behind this behaviour ?

1

AssignTo makes a two-way binding, which allows developers to make components that can interact with their enclosing elements (usually a page). What this means, in practice, is that the setter will be called for assignTo with each transaction.

This creates a race condition, because inpText is bound to two setters. Last one to execute wins. Its hard to know which one will win, because it could change depending on the order of the elements, the compiler optimizations, etc.

In other words, the other methods that you could use to make this work right are not workarounds. They are the correct method for using assignTo. This method isn't correct, and will cause buggy behavior.

The correct way would be to use two setters with a backing variable, two separate variables, or bind the parent element to a controller variable in the parent page, which is initialized once by a constructor.

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.