I've got a JS module which I'm trying to use in lightning. I've decided to wrap the module up in a component of it's own which I could then reuse where needed. One of the parameters for the module is a rendering function which gets called as it works through some data and uses the function to generate some DOM elements which are then appended to an element on the page. I've tried making this module parameter available as an attribute to my wrapper component, but if I try and pass a function to it from a parent component I get the following error:
Error in $A.getCallback() [Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.]
Here's an example of how I've structured the code so far, I've left out the controllers as you can imagine they simply call the helper methods.
ThirdPartyLibWrapper.cmp
<aura:component>
<aura:attribute name="data" type="Object" access="global" />
<aura:attribute name="renderData" type="Object" access="global" />
<aura:attribute name="onReady" type="Aura.Action" default="{!c.init}" access="global" />
<aura:method name="init" action="{!c.init}" access="global" />
<ltng:require scripts="{!$Resource.thirdpartylib + '/thirdpartylib.js'}" afterScriptsLoaded="{!v.onReady}" />
<div id="thirdparty"></div>
</aura:component>
ThirdPartyLibWrapperHelper.js
({
init: function(component)
{
var params = {
data: component.get('v.data'),
renderData: component.get('v.renderData')
};
var thirdPartyLib = new ThirdPartyLib(params);
thirdPartyLib.init();
}
})
ParentComponent.cmp
<aura:component>
<aura:attribute name="data" type="Object" />
<c:ThirdPartyLibWrapper aura:id="lib" data="{!v.data}" onReady="{!c.doInit}" />
</aura:component>
ParentComponentHelper.js
({
doInit: function(component)
{
var lib = component.find('lib');
lib.set('v.renderData', helper.renderData);
lib.init();
},
renderData: function(item)
{
var div = document.createElement('div');
div.innerHTML = item.name;
return div;
}
)}
I understand why I'm getting this message, the locker service is converting the element generated in renderData() in to a SecureElement which isn't a valid element as far as appendChild() is concerned. If I move renderData() to the ThirdPartyLibWrapperHelper.js it works fine. The problem is I want it to be configurable. Any ideas other than turning the Locker Service off?