I believe the Event driven mechanism is probably the right way to handle this,instead of relying on the dataset
attributes on the DOM.Inorder to do so,you have to split the component into two parts:
1.AffiliationsList - (fetches the data) -> Parent Component
2.AffiliationsListItem - (displays each record,fires selected data for edit) -> Child component
AffiliationsList.cmp
<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable" controller="AffiliationController">
<ltng:require styles="/resource/SLDS103/assets/styles/salesforce-lightning-design-system-ltng.min.css"/>
<aura:attribute name="curRecordId" type="String"/>
<aura:attribute name="afList" type="AffiliationWrapper[]"/>
<aura:attribute name="numAf" type="Integer" default="0"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:handler name="appEvent" event="c:affiliationToEdit" action="{!c.editAffiliation}" />
<div class="slds">
<div class="slds-card">
<div class="slds-card__header slds-grid">
<div class="slds-media slds-media--center slds-has-flexi-truncate">
<div class="slds-media__figure">
<c:svg class="slds-icon slds-icon-standard-contact slds-icon--small" xlinkHref="/resource/SLDS103/assets/icons/standard-sprite/svg/symbols.svg#contact"/>
</div>
<div class="slds-media__body">
<h2 class="slds-text-heading--small slds-truncate">Affiliations ({!v.numAf})</h2>
</div>
</div>
</div>
<div class="slds-card__body">
<table class="slds-table slds-table--bordered slds-table--striped slds-max-medium-table--stacked-horizontal">
<thead>
<tr class="slds-text-heading--label">
<th class="slds-is-sortable" scope="col">
<div class="slds-truncate">Relationship
<button class="slds-button slds-button--icon-bare">
<c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
<span class="slds-assistive-text">Relationship</span>
</button>
</div>
</th>
<th class="slds-is-sortable" scope="col">
<div class="slds-truncate">Status
<button class="slds-button slds-button--icon-bare">
<c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
<span class="slds-assistive-text">Status</span>
</button>
</div>
</th>
<th class="slds-is-sortable" scope="col">
<div class="slds-truncate">Project
<button class="slds-button slds-button--icon-bare">
<c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
<span class="slds-assistive-text">Project</span>
</button>
</div>
</th>
<th class="slds-is-sortable" scope="col">
<div class="slds-truncate">Sub-Project
<button class="slds-button slds-button--icon-bare">
<c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
<span class="slds-assistive-text">Sub-Project</span>
</button>
</div>
</th>
<th class="slds-is-sortable" scope="col">
<div class="slds-truncate">Task
<button class="slds-button slds-button--icon-bare">
<c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
<span class="slds-assistive-text">Task</span>
</button>
</div>
</th>
<th class="slds-is-sortable" scope="col">
<div class="slds-truncate">Notes
<button class="slds-button slds-button--icon-bare">
<c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
<span class="slds-assistive-text">Notes</span>
</button>
</div>
</th>
<th class="slds-cell-shrink"></th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.afList}" var="af" indexVar="idx">
<c:AffiliationsListItem afRec="{!v.af}"
</aura:iteration>
</tbody>
</table>
</div>
</div>
</div>
</aura:component/>
AffiliationsListController.js
({
doInit : function(component, event, helper) {
helper.loadAffiliations(component, event);
},
editAffiliation : function(component, event, helper) {
helper.editRecord(component,event);
}
})
AffiliationsListHelper.js
({
loadAffiliations : function(cmp, ev) {
var action = cmp.get("c.getAffiliations");
action.setParams({
"currentId": cmp.get("v.curRecordId")
});
action.setCallback(this, function(response) {
var state = response.getState();
if(state === "SUCCESS") {
var affiliations = response.getReturnValue();
cmp.set('v.numAf', affiliations.length);
cmp.set('v.afList', affiliations);
}
else if (state === "ERROR") {
console.log('errors', response.getError());
}
});
$A.enqueueAction(action);
},
editRecord : function(cmp, ev) {
var row = event.getParam("selectedAffliation");
console.log('row', row);
}
})
Assuming your component level event looks like this :
affiliationToEdit.evt
<aura:event type="COMPONENT" description="Affiliation To Edit Event">
<aura:attribute name="selectedAffliation" type="Object"/>
</aura:event>
AffiliationsListItem.cmp
<aura:component>
<aura:attribute name="afRec" type="Object"/>
<aura:registerEvent name="appEvent" type="c:affiliationToEdit"/>
<tr class="slds-hint-parent slds-has-flexi-truncate">
<td class="slds-truncate slds-cell-wrap" data-label="Relationship">{!v.afRec.relationship}</td>
<td class="slds-truncate" data-label="Status">{!v.afRec.status}</td>
<td class="slds-truncate slds-cell-wrap" data-label="Project">
<a >{!v.afRec.project}</a>
</td>
<td class="slds-truncate slds-cell-wrap" data-label="Sub-Project">{!v.afRec.subProject}</td>
<td class="slds-truncate slds-cell-wrap" data-label="Task">{!v.afRec.task}</td>
<td class="slds-truncate slds-cell-wrap" data-label="Notes">{!v.afRec.note}</td>
<td class="slds-cell-shrink" data-label="Actions">
<ui:button aura:id="edit" label="Edit" press="{!c.editAffiliationRecord}"/>
<!-- <ui:menu>
<ui:menuTriggerLink aura:id="trigger" title="more"/>
<ui:menuList class="actionMenu" aura:id="actionMenu">
<ui:actionMenuItem aura:id="edit" label="Edit" click="{!c.editAffiliation}"/>
<ui:actionMenuItem aura:id="delete" label="Delete" click="{!c.deleteAffiliation}"/>
</ui:menuList>
</ui:menu> -->
</td>
</tr>
</aura:component>
AffiliationsListItemController.js
({ //Fires the event to the parent,to capture the selected affliation record.
editAffiliationRecord : function(component, event, helper) {
var event = component.getEvent("appEvent");
event.setParams({
'selectedAffliation':component.get("v.afRec")
});
event.fire();
}
})
You could use a handler for that.
Add this to your component:
<aura:handler name="change" value="{!v.value}" action="{!c.valueChanged}"/>
v.value
= aura:attribute
c.valueChanged
= method in your lightning controller
Then your ui:input
would be like so:
<ui:inputNumber aura:id="someFld"
class="slds-input"
value="{!v.value}"
change="{c.valueChanged}">
</ui:inputNumber>
Example here.
Best Answer
Not exactly using
apex: variable
, but something similar.Why not add an extra attribute in your array items to store old values? by that way you can compare it every time. Its in JS so your serverside controller will be same.
JS code:
As you can see, I am adding
oldName
in JS for my contact, so that i can directly compare in markup using{!con.Name!=con.oldName?'color: red;':''}
You can do something similar to get job done.