It's about 2 years after I initially touched this issue and today I've found this Known Issue here https://success.salesforce.com/issues_view?id=a1p3A0000008gDzQAI
It confirms my ancient observations from 2015 and confirms also that the Peters fine-grained approach does not work.
For me the recommended workaround is not usefull, since ui:whatever can't out of the box deal with picklists values, field dependencies, translation and localization like number- and date-formats. It can be done, but needs an unjustified amout of complexity and code. My workaround is to use visualforce with it's mature apex:inputField instead.
Here is the Known Issue
<force:inputField>
is not rendering fields on UI when being used
inside <aura:iteration>
tag or inside nested components in Lightning
application
Summary
<force:inputField>
is not rendering fields on UI as expected
when being used inside <aura:iteration>
or inside inner component in
Lightning application
Repro
- Login to your org
- Try creating a sample lightning application
- Create a component with below sample code snippet & try to preview the app
- You will notice the fields doesn't render on the UI as expected.
<aura:component>
<aura:iteration aura:id="iteration" items="{!v.expenses}" var="expenses">
<force:inputField value="{!expenses.Amount__c}"/>
</aura:iteration>
</aura:component>
Workaround
Try using <ui:inputText>
or or
<ui:inputCheckbox>
instead of for rendering input
fields inside <aura:iteration>
or inside inner components
In order to bind to something dynamically, you need a reference. Here is a very basic, no-frills, slightly buggy implementation that demonstrates that this basically works.
Notice how I use component.getReference to dynamically link to a field. Also notice how I can bind to the same field twice, which literally lets me modify the same field more than once in real-time, just to prove that they are real references.
With a little more error checking and fact-gathering, this could indeed be a dynamic form with some basic describe data, etc. Notice how I do not use aura:id at all. I simply bound all the fields to a common object, and I could get and retrieve the values at will (in this case, demonstrated through Object.keys). I could also bind this object to, say, a force:recordData to dynamically save the data back to the server, or send it through a server action in Apex.
<aura:application extends="force:slds">
<aura:attribute name="accountRecord" type="Account" default="{ 'sobjectType': 'Account' }" />
<aura:attribute name="edits" type="Aura.Component[]" />
<aura:attribute name="fieldName" type="String" />
<aura:attribute name="output" type="String" />
<aura:handler name="init" value="{!this}" action="{!c.init}" />
{!v.output}
<hr />
{!v.edits}
<ui:inputText value="{!v.fieldName}" />
<ui:button press="{!c.addField}" label="Add" />
<br/>
<ui:button press="{!c.display}" label="Show Data" />
</aura:application>
({
init: function(component, event, helper) {
component.set("v.edits", []);
},
addField: function(component, event, helper) {
var field = component.get("v.fieldName"),
obj = component.get("v.accountRecord");
obj[field] = "";
component.set("v.accountRecord", obj);
$A.createComponent(
"lightning:input", {
value: component.getReference("v.accountRecord."+component.get("v.fieldName")),
label: component.get("v.fieldName"),
type: "Text"
},
$A.getCallback(function(newCmp, status, error) {
var edits = component.get("v.edits");
edits.push(newCmp);
component.set("v.edits", edits);
})
);
},
display: function(component, event, helper) {
var obj = component.get("v.accountRecord");
var results = [];
Object.keys(obj).forEach(function(key) { results.push(key+":"+obj[key])});
component.set("v.output", results.join('\n'));
}
})
Here's a demo of me dynamically binding stuff:

Best Answer
Expressions need to start with # or ! to be recognized:
Note that the inner
(
and)
are necessary to treat theindex + 1
as arithmetic instead of string concatenation.An expression is always in the form of
{
, followed by#
or!
, followed by the expression to be evaluated, and finally ending in}
.