1

I have a custom component and I'd like to pass an object to it, how do I do it? It's easy to pass a string, but I can't send anything that's observable or not.

main-page.js

exports.onInit = function(args) {
    var page = args.object;
    var pageData = new Observable();

    page.bindingContext = pageData;

    pageData.set('customObject', {label: 'This is my Label'});

    // I've tried Observable as well, same undefined
    // pageData.set('customObject', new Observable({label: 'This is my Label'}));
}

main-page.xml

<Page xmlns:customOtherControls="xml-declaration/mymodulewithxml">
    <customOtherControls:MyControl myString="Works fine" myObject="{{customObject}}" />
    <StackLayout>
        <Label text="{{customObject.label}}" />
    </StackLayout>
</Page>

mymodulewithxml.xml

<StackLayout loaded="onMymodulewithxmlInit">
    <Label text="{{myString}}" />
    <Label text="{{myObject.label}}" />
</StackLayout>

mymodulewithxml.js

function onMymodulewithxmlInit(args) {
    console.log('myString', page.myObject); // "Works fine"
    console.log('myObject', page.myObject); // undefined
}

2 Answers 2

1

If you're wanting to be able to pass in objects and wire up events (i.e. <custom:theWidget data="{{ myDataObj }}" onSave="theSaveCallback" />), you'll need to create a plugin. With a plugin, you can just extend an existing item such as StackLayout, but then you create the property bindings that wire up passing through objects.

When looking through existing plugin examples, pay close attention to the usage of new dependencyObservable.Property(...) as these dependency observables are really the wiring for your custom component's attributes (properties). Here's an example: https://github.com/bradleygore/nativescript-materialdropdownlist/blob/master/materialDropdownList.ts#L92

Sign up to request clarification or add additional context in comments.

Comments

0

This should work for you

main-page.js

var pageData = new Observable();
pageData.set('customObject', {"label" : 'This is my Label'});
pageData.set('someString', "my random string");

exports.onLoaded = function(args) {
    var page = args.object;

    page.bindingContext = pageData;
}

main-page.xml

<Page xmlns:customOtherControls="xml-declaration/mymodulewithxml">
    <customOtherControls:MyControl />
    <StackLayout>
        <Label text="{{customObject.label}}" />
        <Label text="{{someString}}" />
    </StackLayout>
</Page>

mymodulewithxml.xml

<StackLayout loaded="onLoaded">
    <Label text="{{ customObject.label }}" />
    <Label text="{{ someString }}" />
</StackLayout>

mymodulewithxml.js

function onLoaded(args) {
   var stack = args.object;
   // you don't need to pass the context 
   // as the custom component has the parent page bindingContext
   // however if you need different context you can create one 
   // and attach you main-page context entries to the newly created context
   // or even better use MVVM pattern
}

Of course it is even ebtter idea to follow the separation of concerns practice and the MVVM pattern and to separate your view-models in different files from your views.(and then to import them where needed) This way you can easily reuse it with the same structure anywhere in your application.

1 Comment

Hi Nick, thanks for your answer, but that doesn't solve my problem. It's my temporay solution, but I want my custom component with it's own .js with it's own request. It'll call the api depend on few parameters. My custom component should receive the URL and some parameters to call the API. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.