Skip to content

Instantly share code, notes, and snippets.

@NathanWalker
Last active December 13, 2017 15:54
Show Gist options
  • Save NathanWalker/e8f4f7c42af04fc725764a9867936e3d to your computer and use it in GitHub Desktop.
Save NathanWalker/e8f4f7c42af04fc725764a9867936e3d to your computer and use it in GitHub Desktop.
NativeScript: Wire up RadSideDrawer from 'nativescript-telerik-ui' with Angular2 taking full advantage of Router
// angular
import {Component} from '@angular/core';
@Component({
moduleId: module.id,
selector: 'app',
template: `
<StackLayout>
<page-router-outlet></page-router-outlet>
</StackLayout>
`
})
export class AppComponent {
}
import { Routes } from '@angular/router';
// Purely an example
// Change the routes/components to meet your needs
export const routes: Routes = [
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
},
{
path: "home",
component: HomeComponent,
children: [
// '/home' loaded into `router-outlet` in main content
{ path: "", component: StartComponent },
// '/home/otherPath' loaded into `router-outlet` in main content
{ path: "otherPath", component: SomeOtherComponent },
// etc.
]
},
// '/someNavPage' pushed on nav stack using `page-router-outlet` (ie, push on a detail view with no drawer)
{ path: "someNavPage", component: NavPageComponent },
// etc.
];
<ActionBar title="App Title">
<ActionItem (tap)="toggle()">
<!-- example: using font-awesome for hamburger menu but you can use whatever you'd like -->
<Button class="fa" text="&#xf0c9;"></Button>
<!-- however in your project, would be easier to use this plugin: https://github.com/NathanWalker/nativescript-fonticon -->
</ActionItem>
</ActionBar>
<RadSideDrawer #drawer [transition]="sideDrawerTransition" selectionBehavior="None">
<StackLayout tkDrawerContent>
<!-- anything you want in drawer -->
<!-- for example: -->
<!-- you want options {exact: true} on the first one because otherwise it would be considered active when 'Other Page' in active as well -->
<Button text="Home" [nsRouterLink]="['/home']" nsRouterLinkActive="active" [nsRouterLinkActiveOptions]="{exact:true}"></Button>
<Button text="Other Page" [nsRouterLink]="['/home/otherPath']" nsRouterLinkActive="active"></Button>
</StackLayout>
<StackLayout tkMainContent>
<router-outlet></router-outlet>
</StackLayout>
</RadSideDrawer>
// angular
import {Component, ViewChild, ChangeDetectorRef, Inject, OnInit, AfterViewInit} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';
// nativescript
import {RadSideDrawerComponent, SideDrawerType} from 'nativescript-telerik-ui-pro/sidedrawer/angular';
import {DrawerTransitionBase, SlideInOnTopTransition} from 'nativescript-telerik-ui-pro/sidedrawer';
import {Page} from "ui/page";
@Component({
moduleId: module.id,
selector: 'home',
templateUrl: 'home.component.html',
// Using this style here requires you to setup font icons in your project
// See here on how to do that: https://docs.nativescript.org/ui/icon-fonts
// Another nice option is to use this plugin: https://github.com/NathanWalker/nativescript-fonticon
styles: [`
.fa {
font-family: FontAwesome, fontawesome-webfont;
font-size:20;
}
`]
})
export class HomeComponent implements OnInit, AfterViewInit {
@ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
private _sideDrawerTransition: DrawerTransitionBase;
private _drawer: SideDrawerType;
constructor(
@Inject(Page) private _page: Page,
private _changeDetectionRef: ChangeDetectorRef,
private _router: Router) {
_page.on("loaded", this.onLoaded, this);
}
public get sideDrawerTransition(): DrawerTransitionBase {
return this._sideDrawerTransition;
}
public toggle() {
this._drawer.toggleDrawerState();
}
public onLoaded(args) {
this._sideDrawerTransition = new SlideInOnTopTransition();
}
ngOnInit() {
this.router.events.subscribe((e) => {
if (e instanceof NavigationEnd) {
this._drawer.closeDrawer();
}
});
}
ngAfterViewInit() {
this._drawer = this.drawerComponent.sideDrawer;
this._changeDetectionRef.detectChanges();
}
}
// nativescript
// this import should be first in order to load some required settings (like globals and reflect-metadata)
import { NativeScriptModule, platformNativeScriptDynamic } from 'nativescript-angular/platform';
import { NativeScriptFormsModule } from 'nativescript-angular/forms';
import { NativeScriptRouterModule } from 'nativescript-angular/router';
import { SIDEDRAWER_PROVIDERS, SIDEDRAWER_DIRECTIVES } from "nativescript-telerik-ui-pro/sidedrawer/angular";
// app
import {AppComponent} from './app.component';
import {HomeComponent} from './home.component';
// import other components, etc.
import {routes} from './app.routes';
@NgModule({
imports: [
NativeScriptModule,
NativeScriptFormsModule,
NativeScriptRouterModule.forRoot(routes)
],
declarations: [
SIDEDRAWER_DIRECTIVES,
AppComponent,
HomeComponent,
// other components used in routes, etc.
],
providers: [
SIDEDRAWER_PROVIDERS
],
bootstrap: [AppComponent]
})
export class AppModule { }
platformNativeScriptDynamic().bootstrapModule(AppModule);
@abhishekit29
Copy link

There are two routes in that side drawer one to normal page with text the other one to a nativescript-chatview
but on tapping navigation button side drawer is not opening from nativescript-chatview route

@abhishekit29
Copy link

+1

@EddyVerbruggen
Copy link

EddyVerbruggen commented Feb 10, 2017

This Gist saved my ass, thanks Nathan!

There seems to be one major caveat though: due to this line the StartComponent component gets destroyed when navigating away (to otherPath).

So when navigating back StartComponent is recreated. That's a big no no for master-detail navigation where master is a listview and you want to retain the scroll position.

Anyone has an idea how to make sure the components are not destroyed? According to the docs that's actually correct behaviour.. but it renders using the menu useless when nested views are required..

UPDATE: figured it out. The first page after that router-outlet tag needs to be a wrapper page with a page-router-outlet. That will track the state of any consecutive navigation.

@iliraga
Copy link

iliraga commented Mar 8, 2017

Has anybody some project code where this code is used, for example for https://github.com/NativeScript/template-hello-world-ng ? Somehow I'm not able to integrate it into my existing ng2 project.

Everything works, but when opening an other page beside the "home", it has strange rendering issues.
The sidebar gets cut out and will only show partially

@greenstevester
Copy link

@iliraga, I fought with getting the RadSideDrawer going with the Angular Router an posted a working project here: https://github.com/greenstevester/nativescript-sidedrawer-example

@iliraga
Copy link

iliraga commented Mar 9, 2017

Thx a lot @greenstevester ! You're code doesn't work while executing, but it still helped me a lot:

1 0x105fba8d7 -[TNSRuntime executeModule:] 2 0x105793532 main 3 0x10ae6368d start 4 0x1 file:///app/tns_modules/nativescript-angular/index.js:4:8: JS ERROR Error: Could not find module 'application'. Computed path '/Users/ormesijechh/Library/Developer/CoreSimulator/Devices/D9FD7E5E-2224-4F03-B8FF-A4846A5A2395/data/Containers/Bundle/Application/6C641618-56E8-41E3-9782-F50F8F4A0894/nativescriptsidedrawerexample.app/app/tns_modules/application'.

This StackLayout caused the issue. When removing, everything works properly.

@fernandomitre7
Copy link

fernandomitre7 commented Mar 22, 2017

Thanks @greenstevester between you and @NathanWalker I have made progress on implementing the RadSideDrawer, but when running on ios emulator (I have only tested ios) the actual sidedraw is not showing, I get all the events when I click the actionbar button (drawerOpening, drawerOpenned, etc) but I don't see anything. Have you guys encountered this on your projects?
This is my repo

Update: Never mind there was a StackLayout that was off. Thanks!

@adamk33n3r
Copy link

This helped a lot! Is there a way to make it so that the drawer stretches to the whole height of the app though? It looks very odd.

@michellehardatwork
Copy link

michellehardatwork commented Apr 18, 2017

@EddyVerbruggen can you elaborate on your solution for the master-detail-navigation-destroys-the-master fix? If I take the example above and say on SomeOtherComponent I want to navigate (push) to NavPageComponent then I put the page-router-outlet as the first child in "NavPageComponent". I navigate to it using .navigate(["/someNavPage]) on SomeOtherComponent. It appears that SomeOtherComponent gets recreated when going back from NavPageComponent.

I appreciate your help!

@manojdcoder
Copy link

manojdcoder commented May 7, 2017

@NathanWalker / @EddyVerbruggen May I know the work around to prevent the master page from re-created on back navigation?

I tried wrapping the first page after router-outlet with page-router-outlet, but still same issue. Not sure what I am missing. Could you please update this example if possible?

@DrMabuse23
Copy link

i upgrade the example here https://github.com/DrMabuse23/nativescript-nested-navigationtests with the newest versions and structure in with ns >3.0

Copy link

ghost commented Aug 7, 2017

@DrMabuse23 nice example, exactly what I was looking for.

@jdnichollsc
Copy link

you're awesome, thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment