2

What is the use of ApexPages.StandardController in the below?

Code

public class myControllerExtension {
    private final Account acct;
    public myControllerExtension(ApexPages.StandardController stdController) {
        this.acct = (Account)stdController.getRecord();

    }
    public String getGreeting() {
        return 'Hello ' + acct.name + ' (' + acct.id + ')';
    }

}

Markup

<apex:page standardController="Account" extensions="myControllerExtension">
    {!greeting} <p/>
    <apex:form>
        <apex:inputField value="{!account.name}"/> <p/>
        <apex:commandButton value="Save" action="{!save}"/>
    </apex:form>
</apex:page>
1

5 Answers 5

4

When this VisualForce page is loaded, two controllers are instantiated: the standardController for account, and your myControllerExtension. Your VisualForce page can call methos from either of those controllers:

  • The standardController offers out-of-the-box operations like save (either create or update) or delete.
  • Your extension controller can offer custom operations to be performed on the record (in your case, getGreeting).

In order to be able to use the standard operations in the 'standardController', when your extension controller is instantiated, it receives a reference to the standard controller (that's why you need a parameterised constructor).

To clarify: the extension controller is not a child class; it's just another controller class that receives a reference to the standard controller

Hope it helps!

4

A standard controller is a class that provides the common operations needed for Create/Read/Update/Delete (CRUD) operations on any standard or custom object. You tie the standard controller in and let it know the type of your object with e.g.:

<apex:page standardController="Account" ...

That then lets you write Visualforce to view and edit fields of the object and perform operations like saving - your {!save} is invoking the standard controller method - without the need to write any Apex code. The Visualforce can invoke any of these standard methods, and any fields referenced in the Visualforce via a property that is named the same as the object type are automatically queried for you e.g. {!Account.Name}.

In your example you don't necessarily need a controller extension because Visualforce can directly do quite a few things such as create your greeting:

<p>Hello {!Acount.Name} ({!Account.Id})</p>

However, if you want to add more complicated custom logic or data to your page you can do that by writing your own Apex controller extension using the pattern you demonstrate. This lets you add your own functionality on top of what the standard controller already provides rather than having to write everything from scratch. The standard controller and one or more extension controllers that you write are composed (merged together) which is a helpful pattern. As well as making the extension controllers smaller and so more cohesive, it also allows an extension controller to be used with multiple object types if things like hard coded casts are avoided.

A further benefit of basing your page on the standard controller is that you can (optionally) then replace standard pages like the new or edit page with your Visualforce page: the standard "New" or "Edit" buttons and links then launch your Visualforce page not the standard layout-based page. See e.g. Considerations for Overriding Standard Buttons.

3
  • +1 for the mention to composition pattern. Can you elaborate a bit more about that? The extension controller has a reference to the "parent" but they don't seem to implement any common interface or extend controller explicitly. Is this done implicitly by Apex?
    – mkorman
    Jul 16, 2016 at 12:29
  • @mkorman I don't know how its implemented because as you say there isn't much visible in Apex. I assume its some sort of mixin design either through an extra level internal class that is generated or byte code manipulation. I'd speculate its the former to make it easier for Visualforce to just see one class for its bindings.
    – Keith C
    Jul 16, 2016 at 12:38
  • N.B. a slight caution on multiple extension controllers on the same page -- each and every one of them will have their constructor invoked and, if as sometimes done by developers, these constructors do SOQL, page performance can suffer.
    – cropredy
    Jul 16, 2016 at 15:58
0

There are two types of controller, one for standard object, another for custom object. In your sample, for standard object account. The standard controller is bound with all fields and some actions on that standard object. In your case, name and save. But greeting action is not an action already existing on account, so we use extension to extend a custom action. Wish this give you some basics before dive in more.

2
  • Type of controller you defined is wrong.They are not based upon standard object and custom object.You can write standard controller for custom object as well.It just depends upon your need.For more information read @Keith's answer.
    – Mr.Frodo
    Jul 16, 2016 at 12:30
  • My mistake. To correct it - two types of controller, both working for all objects. If you want to customize custom logic for a page should use a custom controller, otherwise we use standard controller to access fields and actions.
    – Helen Y.
    Jul 16, 2016 at 13:01
0

I feel like this piece of the answer is missing and so I'll add that whenever you use the standardController attribute on an <apex:page> tag, it enables some useful functionality:

  • Use the Visualforce Page in a new Custom Button
  • Override standard buttons with the Visualforce Page
  • Embed the Visualforce Page in a Page Layout

If you want to additionally specify the extensions property on your <apex:page>, your extension must have a constructor defined that accepts the ApexPages.StandardController already generated by the page.

public with sharing class MyExtension
{
    public MyExtension(ApexPages.StandardController controller)
    {
        // your page won't compile with this extension enabled
        // unless you define this constructor
    }
}

If you additionally specify the recordSetVar attribute, you can use it on List buttons instead. However, this requires a different constructor, because now there is no ApexPages.StandardController being passed in, but rather ApexPages.StandardSetController.

public with sharing class MyExtension
{
    public MyExtension(ApexPages.StandardSetController controller)
    {
        // if you use recordSetVar and this extension,
        // your page won't compile unless you define this constructor
    }
    public MyExtension(ApexPages.StandardController controller)
    {
        // you can define both
    }
    public MyExtension()
    {
        // if you want to use the controller as a standalone also
        // you must manually define the empty constructor
        // using all three in the same Apex Class is rare
    }
}
-1

In my thoughts,

standardController="Account" extensions="myControllerExtension"

myControllerExtension is the child class of standardController or constructor for a standard controller. so ApexPages.StandardController will give the standardController fields values those are included in VF page then to perform the standard save method for create new standardController record.

1
  • 2
    That is not 100% accurate. myControllerExtension is not a child class.
    – mkorman
    Jul 16, 2016 at 12:19