2

So consider a component with an attribute like this:

<apex:attribute name="rentalContract" type="RentalContract__c" assignTo="{!rentalContract}"/>

And this is how my controller looks like:

public with sharing class RentalContractController {
    public RentalContract__c rentalContract { get; set; }
}

As you all may probably know this will not work anymore with API >= 27 because in Spring '13 they introduced Compile-Time Checking for Custom Component Attribute Names which basically means that the name for your attribute cannot be the same name that you assign to.

The release notes further state:

To make this component compile under API version 27.0, change either the attribute name or the assignTo value (which might require you to also change a controller method or property).

So this is all nice and dandy - but how do you really solve it? Because if I do make a custom controller I likely name its main variable after its object. Plus it's similar to standard controllers where you can just use the object name as the variable - so it's very similar to this.

On the other hand - when I do make a component I likely name the variables after the objects they use. Which works fine until I want to wire this up with a controller which is using the same name. And then I end up renaming one or the other - which might or might not work so good in a managed package, plus it can involve a lot of renaming and unnecessary code changes.

So my question is: Is there some kind of pattern, idiom, whatever ... that you've come up with that prevents events like this? I would tend to always name the attribute in the component not exactly after the object because I think that is easier to change - but in what way? Because options like myRentalContract or theRentalContract clearly show that this is purely a technical fix plus it isn't really obvious to the developer using it. So imho that is a bad solution to an unnecessary problem.

I've run into this problem so many times that I really want a good solution for this so I don't have to think about naming these things so much - because as you all may remember - naming things is the hardest and it takes a lot of time. In this case it takes way too much time.

3

Using generic terms on one side or the other can help. So instead of rentalContract, use record (single instance of an SObject) or, instead of rentalContractId, use recordId. Even these two alone give you a lot more flexibility.

In general, I would try to put the more generic names as the outward facing attributes.

Component

<apex:component controller="MyController">
    <apex:attribute type="Id" name="recordId" assignTo="{!myObjectId}" />
</apex:component>

Controller

public with sharing class MyController
{
    public Id myObjectId { get; set; }
}

In this way, your references to custom built components will be more consistent.

<c:customComponent1 recordId="{!someId}" />
<c:customComponent2 record="{!someRecord}" />
  • Do you do this in the component or the controller? What's your rule - if you have one? – Semmel Sep 7 '16 at 11:32
  • 1
    I would say it probably works better to make the outward facing variables generic. It will make your markup more consistent and recognizable. Perhaps, you might even call it idiomatic in that sense. – Adrian Larson Sep 7 '16 at 11:36
  • Sounds reasonable. Generic in what sense? – Semmel Sep 7 '16 at 11:58
  • As in record and recordId above. – Adrian Larson Sep 7 '16 at 11:59
  • 1
    I'm saying the attribute is outward facing. As in, if you do <c:myComponent attribute="value" />, that is what other developers are mostly going to work with, and the piece of the puzzle you would want to be more generic. – Adrian Larson Sep 7 '16 at 13:01
0

Even though in your question you sound like you aren't in favor of using names like myRentalContract or theRentalContract, I still think that this is going to be the best solution. As long as you are consistent, it's going to be easier than trying to remember two separate sets of names for essentially the same thing.

I'd say the place to make the change is in all of the component attribute names since you will probably have more controller properties in your code base that aren't used in component attributes than vice-versa.

I personally like the idea of prefixing all of the attribute names with the letter c since components from non-managed packages have the letter c as a namespace.

<apex:component
 controller="RentalContractController"
>
    <apex:attribute 
     name="cRentalContract" 
     assignTo="{!RentalContract}"
     type="RentalContract__c" 
    />
...
</apex:component>

<apex:component>
    <c:RentalContractComponent
     cRentalContract = "{!RentalContract}"
    />
</apex:component>

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.