如何让 Nativescript-ui-sidedrawer 进行横向导航?

Posted

技术标签:

【中文标题】如何让 Nativescript-ui-sidedrawer 进行横向导航?【英文标题】:How to make Nativescript-ui-sidedrawer perform lateral navigation? 【发布时间】:2019-09-14 10:59:57 【问题描述】:

我正在尝试借助侧抽屉在我的应用中实现横向导航。

我的应用有一个“开始”组件,它是一种“欢迎”页面和 32 个包含必要内容的“主题”。

我需要用户能够使用 Sidedrawer 内容从一个主题转到另一个主题,而无需返回到开始页面。

现在我可以成功地从起始页导航到例如“主题 6”。但是为了导航到另一个主题,比如“主题 12”,我需要按“返回”并返回到开始屏幕。当我在主题屏幕上时,侧抽屉的主题按钮不起作用。

代码如下:

app.component.html 带侧抽屉

<RadSideDrawer [drawerTransition]="sideDrawerTransition">
  <GridLayout tkDrawerContent  rows="auto, *">
    <StackLayout class="sidedrawer-header">
    <Image src="res://header" stretch="aspectFit" ></Image>
    </StackLayout>
    <ScrollView row="1" class="sidedrawer-content">
       <StackLayout >
        <Button
        *ngFor="let topic of topics"
        [text]="topic.title"
        [class.selected]="isComponentSelected('/unitsContent/' + topic.id)"
        (tap)="onNavItemTap('/unitsContent/' + topic.id)"
        class="btn">
        </Button>
       </StackLayout>
    </ScrollView>
   </GridLayout>
<page-router-outlet tkMainContent></page-router-outlet>
</RadSideDrawer>

app.component.ts

import  Component, OnInit, ViewChild  from "@angular/core";
import  NavigationEnd, Router  from "@angular/router";
import  RouterExtensions  from "nativescript-angular/router";
import  DrawerTransitionBase, RadSideDrawer, SlideInOnTopTransition from "nativescript-ui-sidedrawer";
import  Topic  from "./data/topic";
import  TOPICS  from "./data/topics-collection";
import  TopicService  from "./data/topic.service";
import  filter  from "rxjs/operators";
import * as app from "tns-core-modules/application";

@Component(
    selector: "ns-app",
    moduleId: module.id,
    templateUrl: "./app.component.html"
)
export class AppComponent implements OnInit 

    private _activatedUrl: string;
    private _sideDrawerTransition: DrawerTransitionBase;

    topics: Topic[];

    getTopics(): void 
      this.topicService.getTopics()
          .subscribe(topics => this.topics = topics);
    

    constructor(private router: Router, private routerExtensions: RouterExtensions, private topicService: TopicService) 
        // Use the component constructor to inject services.
    

    ngOnInit(): void 
        this.getTopics();

        this._activatedUrl = "/start";
        this._sideDrawerTransition = new SlideInOnTopTransition();

        this.router.events
        .pipe(filter((event: any) => event instanceof NavigationEnd))
        .subscribe((event: NavigationEnd) => this._activatedUrl = event.urlAfterRedirects);
    

    get sideDrawerTransition(): DrawerTransitionBase 
        return this._sideDrawerTransition;
    

    isComponentSelected(url: string): boolean 
        return this._activatedUrl === url;
    

    onNavItemTap(navItemRoute: string): void 
        this.routerExtensions.navigate([navItemRoute], 
            transition: 
                name: "fade"
            , clearHistory: true
        );

        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.closeDrawer();
    

app-routing.module.ts

import  NgModule  from "@angular/core";
import  NativeScriptRouterModule  from "nativescript-angular/router";
import  Routes  from "@angular/router";

const routes: Routes = [
     path: "", redirectTo: "/start", pathMatch: "full" ,
     path: "start", loadChildren: "~/app/start/start.module#StartModule" ,
     path: "unitsContent/:id", loadChildren: "~/app/unitsContent/unitsContent.module#UnitsContentModule" ,

];

@NgModule(
    imports: [NativeScriptRouterModule.forRoot(routes)],
    exports: [NativeScriptRouterModule]
)
export class AppRoutingModule  

app.module.ts

import  NgModule, NO_ERRORS_SCHEMA  from "@angular/core";
import  NativeScriptModule  from "nativescript-angular/nativescript.module";
import  NativeScriptUISideDrawerModule  from "nativescript-ui-sidedrawer/angular";

import  AppRoutingModule  from "./app-routing.module";
import  AppComponent  from "./app.component";

@NgModule(
    bootstrap: [
        AppComponent
    ],
    imports: [
        NativeScriptModule,
        AppRoutingModule,
        NativeScriptUISideDrawerModule
    ],
    declarations: [
        AppComponent,

    ],
    providers: [],
    schemas: [
        NO_ERRORS_SCHEMA
    ]
)

export class AppModule  

unitsContent.component.ts一个主题组件

import  Component, OnInit  from "@angular/core";
import  RadSideDrawer  from "nativescript-ui-sidedrawer";
import  ActivatedRoute  from '@angular/router';
import  TopicService from '../data/topic.service';
import  Topic  from '../data/topic';


import * as app from "tns-core-modules/application";

@Component(
    selector: "UnitsContent",
    moduleId: module.id,
    templateUrl: "./unitsContent.component.html"
)
export class UnitsContentComponent implements OnInit 
    topic: Topic;

    constructor(
      public route: ActivatedRoute,
      public topicService: TopicService
    ) 
        // Use the component constructor to inject providers.
    

    ngOnInit(): void 
        // Init your component properties here.
        this.getTopic();
    

    getTopic(): void 
      const id = +this.route.snapshot.paramMap.get('id');
  this.topicService.getTopic(id)
    .subscribe(topic => this.topic = topic);
     

    onDrawerButtonTap(): void 
        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.showDrawer();
    


unitsContent.component.html

<ActionBar class="action-bar">
  <NavigationButton ios:visibility="collapsed" icon="res://baseline_menu_white_24" (tap)="onDrawerButtonTap()"></NavigationButton>
  <Label class="action-bar-title" [text]="topic.title" horizontalAlignment="left"></Label>
</ActionBar>
<StackLayout>
<GridLayout rows="*, *, *, *" columns="*, *">
  <Button text="Button 1" row="0" col="0" rowSpan="3" class="btn"></Button>
  <Button text="Button 2" row="0" col="1"  rowSpan="3" class="btn"></Button>
  <Button text="Button 3" row="3" col="0" colSpan="2" class="btn"></Button>
</GridLayout>
</StackLayout>

unitsContent.module.ts

import  NgModule, NO_ERRORS_SCHEMA  from "@angular/core";
import  NativeScriptCommonModule  from "nativescript-angular/common";

import  UnitsContentRoutingModule  from "./unitsContent-routing.module";
import  UnitsContentComponent  from "./unitsContent.component";

@NgModule(
    imports: [
        NativeScriptCommonModule,
        UnitsContentRoutingModule
    ],
    declarations: [
        UnitsContentComponent
    ],
    schemas: [
        NO_ERRORS_SCHEMA
    ]
)
export class UnitsContentModule  

unitsContent-routing.module.ts暂时没有路由,但我计划稍后导航“更深”。

import  NgModule  from "@angular/core";
import  Routes  from "@angular/router";
import  NativeScriptRouterModule  from "nativescript-angular/router";

import  UnitsContentComponent  from "./unitsContent.component";

const routes: Routes = [
     path: "", component: UnitsContentComponent ,
];

@NgModule(
    imports: [NativeScriptRouterModule.forChild(routes)],
    exports: [NativeScriptRouterModule]
)
export class UnitsContentRoutingModule  

【问题讨论】:

由于您在抽屉中使用页面路由器出口,它保留了路由器的历史记录。在导航时将clearHistory 设置为true 将清除路由器历史记录中的先前页面。 感谢您的回复。改为“真”。还是不行。编辑了问题正文。 你能分享一个可以重现问题的最小 Playground 示例吗? 当然。会尝试。我将能够在 6-7 小时内完成。 这里是重现问题的操场示例play.nativescript.org/?template=play-ng&id=Lf87p6&v=7 【参考方案1】:

看来我自己找到了答案。 结果证明这是一个纯粹的 Angular 东西。在我的应用程序中,我指的是同一个组件。唯一改变的是我的路线参数。路由器只有在导航到不同的路由时才会销毁并重新创建组件。当只更新路由参数或查询参数但路由相同时,组件不会被销毁和重新创建。

我在这里找到了答案:Router Navigate does not call ngOnInit when same page

所以我这样修改了我的 unitsContent.component.ts

import  Component, OnInit  from "@angular/core";
import  RadSideDrawer  from "nativescript-ui-sidedrawer";
import  ActivatedRoute  from '@angular/router';
import  TopicService from '../data/topic.service';
import  Topic  from '../data/topic';


import * as app from "tns-core-modules/application";

@Component(
    selector: "UnitsContent",
    moduleId: module.id,
    templateUrl: "./unitsContent.component.html"
)
export class UnitsContentComponent implements OnInit 
    topic: Topic;

    constructor(
      public route: ActivatedRoute,
      public topicService: TopicService
    ) 
        // This part forces the component recreation with the new params
       route.params.subscribe(val => 
         this.ngOnInit();
        );
    

    ngOnInit(): void 
        // Init your component properties here.
        this.getTopic();
    

    getTopic(): void 
      const id = +this.route.snapshot.paramMap.get('id');
  this.topicService.getTopic(id)
    .subscribe(topic => this.topic = topic);
     

所以它解决了我的问题。

【讨论】:

以上是关于如何让 Nativescript-ui-sidedrawer 进行横向导航?的主要内容,如果未能解决你的问题,请参考以下文章

Jfreechart柱状图如何让变成纯色

android中如何让文字环绕图片

如何让GridView 标题居中

请教如何让UIActivityIndicatorView永远居中

如何让ActionBar标题居中

EBS如何让从值集不显示