[SalesForce] Calling Component Controller from VF Page

I have a VisualForce page with a list of objects on one side and a section on the right that shows details about the objects. The section on the right is a VF Component. The component controller has a method that looks up the details based on the object's ID.

The idea is when the user clicks on the list, the component updates. Now, I know how to define an ActionFunction, and to call a method on the page controller via Javascript in response to the onclick. But how do I call a method on the component controller to update the ID and have it reload it's data?

Best Answer

The easiest way is to do so via an attribute on the component.

<apex:component controller="XYZ">
   <apex:attribute name="recordId" description="The record to view" assignTo="{!currentRecordId}" />

And in the controller:

public class XYZ {
    Id recordId;
    public void setCurrentRecordId(Id newRecordId) {
        if(newRecordId != recordId) {
            recordId = newRecordId;
            reloadData();
        }
    }
    // reloadData and related attributes not included
}

At that point, all you need to do is set the selected record Id in your page's controller/extension, and the assignTo function will notify your component of the change. Strictly speaking, you don't need an actionFunction, just a normal action method would work as well.


In the page:

<c:myComponent recordId="{!selectedRecordId}" />

...

<apex:repeat value="{!itemList}" var="item">
    {!item.name} <apex:commandLink action="{!item.selectRecordId}" />
</apex:repeat>

And in your controller:

public class pageController {
    public Id selectedRecordId { get; set; }
    public class Wrapper {
        pageController controller;
        public SObject record { get; set; }
        public void selectRecordId() {
            controller.selectedRecordId = record.Id;
        }
    }
    public Wrapper[] itemList { get; set; }
    // set itemList to the values for the wrapper
}