Aaron Ullal
Aaron Ullal

Reputation: 5245

Nativescript ActionBar custom component

I am trying to create a custom component as described here in order to reuse the action bar and its logic in different places of my app. Here is what I have setup the component:

/components/header/header.xml

<ActionBar title="Title" class="{{ 'mode' == dark ? 'bg-dark' : 'bg-white' }}" loaded="loaded">
</ActionBar>

/components/header/header.ts

exports.loaded = (args) => {
    let page = <Page> args.object;
    let pageObservable = new Observable({
        'mode' : page.get('mode')
    });
    page.bindingContext = pageObservable;
}

I then try to use the component calling it like this :

some_view.xml

<Page 
 xmlns="http://schemas.nativescript.org/tns.xsd"
 xmlns:header="components/header">

<header:header mode="dark"/>
<StackLayout>..</StackLayout>
...
</Page>

However, navigating to `some-view.xml' I get the following error:

Calling js method onCreateView failed
TypeError: Cannot read property frame of 'undefined'
File "data...../ui/action-bar/action-bar.js" line: 146 

Am I doing something wrong? Have you succeded in creating a custom component based on ActionBar?

Upvotes: 0

Views: 1472

Answers (1)

Nikolay Tsonev
Nikolay Tsonev

Reputation: 1919

Perhaps the problem is that you are trying to get Page instance in the loaded method in your /components/header/header.ts file. args will return you reference to the ActionBar instead of Page. On other hand while using TypeScript the events should be defined like this export function loaded(args){...}. In the above-given code you are using JavaScript syntax. I am attaching sample code, where has been shown, how to create custom component.

component/action-bar/action-bar.xml

<ActionBar loaded="actionbarLoaded" title="Title" icon="">
    <NavigationButton text="Back" icon="" tap="" />
    <ActionBar.actionItems>
        <ActionItem icon="" text="Left" tap="" ios.position="left" />
        <ActionItem icon="" text="Right" tap="" ios.position="right" />
    </ActionBar.actionItems>
</ActionBar>

component/action-bar/action-bar.ts

export function actionbarLoaded(args){
     console.log("actionbar loaded");
 }

main-page.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" xmlns:AB="component/action-bar">
<Page.actionBar>
     <AB:action-bar />
</Page.actionBar>
  <StackLayout>
    <Label text="Tap the button" class="title"/>
    <Button text="TAP" tap="{{ onTap }}" />
    <Label text="{{ message }}" class="message" textWrap="true"/>
  </StackLayout>
</Page>

main-page.ts

import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';

// Event handler for Page "navigatingTo" event attached in main-page.xml
export function navigatingTo(args: EventData) {
  // Get the event sender
  let page = <Page>args.object;
  page.bindingContext = new HelloWorldModel();
}

Upvotes: 1

Related Questions