Suppose I create a small component that takes an input and sets a label to show it.
app/components/testComponent/testComponent.xml:
<Label id="someLabel" loaded="onLoad"/>
app/components/testComponent/testComponent.js:
exports.onLoad = args => {
const obj = args.object;
const label = obj.getViewById('someLabel');
label.text = obj.someString || 'no string given';
};
Now I can use this component in any of my pages
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:testComponent="components/testComponent">
<StackLayout>
<testComponent:testComponent someString="hello {N}"/>
</StackLayout>
</Page>
This seems to be the official way to do it and it works. But is there a way to inject this component in the page using javascript only?
Yes, the Declarative UI (i.e. xml) is actually a building system that parses the xml and generates the JS so you don't have to.
So if you wanted to manually do this you would leave your component code alone and you would change your main screen code to be like this:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onLoad">
<StackLayout id='sl'>
</StackLayout>
</Page>
The first thing you will notice is we gave the Page a loaded event, you have to have somewhere to actually run your code to attach your component to the visual tree. The second thing we did was add to StackLayout an id; this technically isn't actually needed -- you can navigate the NS tree and find the proper StackLayout; but for simplicity adding a ID makes it a lot easier.
So the JS code in your page would be:
var builder = require('ui/builder');
var fs = require('file-system');
exports.onLoad = function(args) {
// Get our current Page that is being loaded
var page = args.object;
// Find our StackLayout
var stackLayout = page.getViewById('sl');
// Load our JS for the component
var path = fs.knownFolders.currentApp().path;
var componentJS = require(path + '/components/testComponent/testComponent.js');
// Actually have the builder build the Component using the XML & JS.
var component = builder.load(path + '/components/testComponent/testComponent.xml', componentJS);
// And add our component to the visual tree
stackLayout.addChild(component);
};
I believe that because you are adding the child in the loaded event that your page loaded event in the child component will be ran, but don't hold me to that one. If it isn't then you can manually run it a the same time you are adding it...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With