9

Browsing forcedotcom/aura GitHub repo I faced some interesting components

<aura:locator>

<aura:locatorContext>

Then I inserted some meaningless snippet into my foo.cmp lightning component and It deployed without any error:

<aura:locator target="anchor" alias="menu-item" isPrimitive="true" description="Action item button">
        <aura:locatorContext key="devNameOrId" value="{!v.id}"/>
</aura:locator>

So that means that these components are supported by Lightning Aura Framework and compatible within lightning components. I didn't find any docs or mentions about them.

So the questions are:

Is there any useful application of <aura:locator> and <aura:locatorContext>?

How do they work and what are their attributes responsible for?

5
+50

Short version: Salesforce customers cannot do anything with those components as the necessary APIs to leverage them are not exposed (anymore). In the framework they seem to be used to better handle/identify the transaction context in nested component situations.

Long version:

I checked the original commit for this component.

The test description for the locator components reads:

     /**
     * 1. Click on an element contained inside another component that is included in our component.
     * 2. Get the transaction that happened as a result of clicking on the element.
     * 3. Verify the target of the transaction is the element we clicked on.
     * 4. Verify the scope is the component that contained the actual element.
     * 5. Verify the context information is as expected.
     */

In this commit, I also learned about component.prototype.getLocator(localId) or .getLocatorDefs() and especially .resolveLocator() as part of the AuraExpressionService or AuraComponentService - neither of which are accessible (anymore) on the platform.

resolveLocator seems to be the main 'feature' here, which gives you a bunch of information:

* @returns This will produce a locator that combines information as such:
 *          + root localId as target with context provided by parent->root locator
 *          + parent localId as scope with context provided by grandparent->parent locator
 */

Still not satisfied, I tried to rebuild one of the test components:

/* locator.cmp*/ 
<aura:component >
    <aura:attribute name="innerTextValue" type="String"/>
    <aura:attribute name="addText" default="someText" type="String"/>

    <aura:locator target="innerWithAuraIdLocator" description="Inner Div Locator">
        <aura:locatorContext key="innerTextValue" value="{!v.innerTextValue + v.addText}"/>
    </aura:locator>

    <div class="innerWithAuraIdLocator" aura:id="innerWithAuraIdLocator" onclick="{!c.clickHandler}">
        {!v.innerTextValue + ' | inner has auraid and locator'}
    </div>

    <div class="innerWithAuraIdNoLocator" aura:id="innerWithAuraIdNoLocator" onclick="{!c.clickHandler}">
        {!v.innerTextValue + ' | inner has auraid without locatordef'}
    </div>

    <div class="innerWithoutAuraId" onclick="{!c.clickHandler}">
        {!v.innerTextValue + ' | inner has NO auraid'}
    </div>

    <div class="innerWithAuraIdDataRef" aura:id="innerWithAuraIdDataRef" onclick="{!c.clickHandler}">
        {!v.innerTextValue + ' | inner has auraid without locator def but uses data-refid'}
    </div>
</aura:component>
/*locatorController.js*/
({
    clickHandler: function(cmp, event, helper) {
        // do nothing, but we do need this handler 
        // setup so that click handlers are added
    }
})
/*locatorRenderer.js*/
({
    render: function (cmp) {
        var ret = this.superRender();
        var element = ret[3];
        element.setAttribute("data-refid", "keyRef");
        element.setAttribute("data-keyRef", cmp.get("v.innerTextValue"));
        return ret;
    }
})

And put it into a testApp

/*testApp.app*/
<aura:application extends="force:slds">

    <div class="slds-p-around_medium">
        <lightning:button label="Click Me" onclick="{!c.onClick}" aura:id="clickMeButton"/>
    </div>
    <aura:handler name="init" value="{!this}" action="{!c.init}"/>
    <aura:attribute name="wrapperText" default="Inner Text Set from locatorWrapper" type="String"/>
    <aura:attribute name="parentKeyAppend" default=" abc" type="String"/>

    <aura:locator target="locatorWrapperIdWithDef" description="Locator defined on wrapper">
        <aura:locatorContext key="parentKey" value="{!v.wrapperText}"/>
    </aura:locator>

    <div class="locatorWrapperIdNoDef">
        <c:locator aura:id="locatorWrapperIdNoDef" innerTextValue="{!v.wrapperText + ' | Parent has auraid without locator def'}"/>
    </div>

    <div class="locatorWrapperNoAuraId">
        <c:locator innerTextValue="{!v.wrapperText + ' | Parent does NOT have auraid'}"/>
    </div>

    <div class="locatorWrapperIdWithDef">
        <c:locator aura:id="locatorWrapperIdWithDef" innerTextValue="{!v.wrapperText + ' | Parent has auraid with locator def'}"/>
    </div>
</aura:application>
/*testAppController.js*/
({
    onClick : function(component, event, helper) {
        debugger;
    },

    init : function(component, event, helper) {
        //empty
    }
})

It all compiles fine and displays but that is as far as I got. Whereas I could simulate a click as in the aura test, I have no metricsService to verify the transaction context myself. As explained above, the necessary APIs/functions on component level to actually use locatorContext are not exposed within Salesforce.

As for the appearance of aura:locator in the documentation for the pre-chat ui, I am guessing that the pre-chat interfacelightningsnapin:prechatUI makes use of aura:locator to handle interaction within its nested structure more gracefully.

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.