As far as I can tell, Lightning components don't support that dynamic reference syntax.
You could consider dynamically generating the content of this component with the component controller:
Component
<aura:component controller="GetAFewContacts">
<aura:attribute name="contacts" type="Contact[]" />
<aura:attribute name="fieldNames" type="String[]" default='["Id","Name"]'/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
{!v.body}
</aura:component>
Client-side Controller
({
doInit : function(component, event, helper) {
var action = component.get("c.getContacts");
action.setCallback(this,function(response){
if (response.getState() === "SUCCESS"){
console.log(response.getReturnValue());
component.set("{!v.contacts}",response.getReturnValue());
var contacts = component.get("{!v.contacts}");
var fieldNames = component.get("{!v.fieldNames}");
var NewBody = "";
for (var i=0; i<contacts.length; i++){
for (var ii=0; ii<fieldNames.length; ii++){
NewBody += contacts[i][fieldNames[ii]];
}
NewBody += "\n";
}
console.log(NewBody);
$A.createComponent(
"ui:outputText",
{
"value" : NewBody
},
function(newComponent){
component.set("v.body",newComponent);
}
)
}
}
);
$A.enqueueAction(action);
}
})
Server-side Controller
public class GetAFewContacts {
@AuraEnabled
public static list<Contact> getContacts(){
return [SELECT Id, Name FROM Contact LIMIT 10];
}
}
Or you could use a second component that sets the value through the component's renderer:
Component
<aura:component controller="GetAFewContacts">
<aura:attribute name="contacts" type="Contact[]" />
<aura:attribute name="fieldNames" type="String[]" default='["Id","Name"]'/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<aura:iteration items="{!v.contacts}" var="contact" >
<aura:iteration items="{!v.fieldNames}" var="fieldName">
<analysis:ContactAndFieldName contact="{!contact}" fieldName="{!fieldName}" />
</aura:iteration>
</aura:iteration>
</aura:component>
Client-side Controller
({
doInit : function(component, event, helper) {
var action = component.get("c.getContacts");
action.setCallback(this,function(response){
if (response.getState() === "SUCCESS"){
component.set("{!v.contacts}",response.getReturnValue());
}
}
);
$A.enqueueAction(action);
}
})
Server-side Controller
public class GetAFewContacts {
@AuraEnabled
public static list<Contact> getContacts(){
return [SELECT Id, Name FROM Contact LIMIT 10];
}
}
Component -- ContactAndFieldName
<aura:component >
<aura:attribute name="contact" type="Contact" />
<aura:attribute name="fieldName" type="String" />
<ui:outputText aura:Id="outputTextId" />
</aura:component>
ContactAndFieldNameRenderer
({
render : function(component, helper) {
var ret = this.superRender();
var Contact = component.get('v.contact');
var FieldName = component.get('v.fieldName');
var outputText = component.find("outputTextId");
outputText.set("v.value",Contact[FieldName]);
return ret;
},
})
If an init event is used instead of putting the javascript in the renderer:
Component -- ContactAndFieldName
<aura:component >
<aura:attribute name="contact" type="Contact" />
<aura:attribute name="fieldName" type="String" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<ui:outputText aura:Id="outputTextId" />
</aura:component>
ContactAndFieldNameController
({
doInit : function(component, helper) {
var Contact = component.get('v.contact');
var FieldName = component.get('v.fieldName');
var outputText = component.find("outputTextId");
outputText.set("v.value",Contact[FieldName]);
}
})
(no custom renderer, and everything else is the same)
aura:iteration
.. Basically in this second component use JAVSCRIPT to get the value from object like ex.obj[fieldapi]