Angular + Nativescript 代码共享项目删除操作栏

Angular + Nativescript Code Sharing Project Remove Action Bar

我的项目正在使用 Angular + Nativescript 代码共享项目为 Android 和 IOS.

的 Web 和移动设备构建

问题是试图删除整个应用程序的操作栏。我已经阅读了一些关于这个问题的帖子,但是 none 的解决方案似乎有效,或者至少最终不是一个很好的解决方案。

我尝试添加 <Page actionBarHidden="true"></page> 但这在 app.component 或其他包含路由的组件中根本不起作用,例如带有路由 [=17= 的 home.component ].如:

<Page actionBarHidden="true">
  <StackLayout orientation="vertical">
    <Image src="res://buy" stretch="none" horizontalAlignment="center"></Image>
  </StackLayout>
</Page>

我还尝试了一种专门针对 android 的方法,看看我是否可以通过 AndroidManifest.xml 文件解决这个问题,就像我通过更新 Android 制作原生 Android 应用程序一样。 =47=] manifest 带走操作栏。为了进行完整性测试,我还尝试通过 styles.xml 使用它,例如:

<style name="AppThemeNoActionBar" parent="AppTheme">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

在这些失败的尝试之后,我尝试了以下涉及 Page 的其他人推荐的代码,例如:

import { Page } from 'tns-core-modules/ui/page';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  ngOnInit() {
    this.page.actionBarHidden = true;
  }
}

此方法的问题是要使此解决方案起作用,我需要为每个具有路由的组件创建一个 tns 文件,只是为了调用它来完全删除应用程序栏,因为每个页面似乎都处理他们自己的应用程序栏。现在这并不是真正可大规模维护的,而且它迫使我为所有具有路由的组件创建一个 tns 文件。

最后,我看到了一个示例,其中我们有一个服务具有针对 this.page.actionBarHiddenrootFrame.actionBarVisibility = 'never' 的逻辑,您可以在 component.ts 文件中调用它而无需创建一个 component.tns.ts 文件,但是现在的问题是您需要创建一个具有要调用的空函数的常规服务,为实际逻辑创建该服务的 tns 文件,以及必须在每个有路由的组件中调用它。

如您所见,有些解决方案根本行不通,而另一些则需要大量额外代码和可维护性,尤其是随着应用程序的增长,它们并不是非常理想的解决方案。

我会继续研究这个问题,我相信必须有一个干净的解决方案。

经过更多研究和测试后,我找到了一个按预期工作的解决方案。以及我将解释为什么其他一些方法没有按预期工作的原因。

首先是 <Page actionBarHidden="true">。根据我的研究和测试,这仅在您专门为 nativescript 构建而不是作为 Angular + Nativescript 代码共享项目时才有效。这样做的原因是,当我们使用 Angular 进行 Web 开发时,我们正在使用 <router-outlet></router-outlet>,对于 Angular 的新手,这会处理更改应用程序内的路由并根据路由显示正确的组件.

现在,当我们开始编写 Nativescript 时,我们希望尽可能多地重用代码,包括我们的路由。在这种情况下,我们最终会在 app.component.tns.html 文件中使用 <page-router-outlet></page-router-outlet>。很像 Angular 当我们改变路线时,这将控制基于路线的正确组件的显示。

问题的发生是因为 <page-router-outlet></page-router-outlet> 自动为我们创建了一个 <Page></Page>。因此,无论是 app.component.tns.html 还是 home.component.tns.html,将一个放在我们的模板中都不会起作用,因为它已经有了一个我们无法在我们的 html 文件中轻松引用它。

对于尝试通过 App_Resources 文件夹中的 android 清单执行此操作的问题,我也没有成功。我相信是因为当我们使用 <page-router-outlet></page-router-outlet> Nativescript 时会在内部更改清单以反映并默认强制我们使用操作栏。我试过用几种不同的方式设置它,不管它是一样的。我能够通过 Platform 文件夹让它工作,但是我不推荐这样做,因为有时我们需要删除和添加平台,这可能会导致我们忘记或不得不继续实施相同的解决方案,浪费宝贵的开发时间。

下一期使用this.page.actionBarHidden = true;本期与第一期属于同一类别。当您尝试在 app.component.tns.ts 文件中执行此操作时,它永远不会单独使用该命令,因为我们正在使用 <page-router-outlet></page-router-outlet>。本质上 AppComponent 根本看不到该页面,因为它不属于它。当应用程序加载时,如果您的第一个默认路由指向 home 组件,那么您需要在 Home 组件中使用 this.page.actionBarHidden。但是,为了在 web 中不失败,您需要为每个组件创建一个 tns 文件,该文件有一个路由以在其中专门包含该逻辑,而这在可维护性方面是不切实际的。

对于最后一期,我们不应该重复代码。在这种情况下,将在每个 component.tns.ts 文件上调用该函数,只是为了删除我们想要在应用程序范围内使用的内容。以及创建我们不需要的额外 tns files 和管理另一项服务 运行 一段仅适用于 nativescript 的代码。

解决方案

这是我能找到的最简单的解决方案,它允许在一个位置处理操作栏,以便随时轻松更改。解决方法是使用Angular的Router。我们在 ngOnInit 中所做的是订阅路由器的事件。然后当 Router 事件触发时,我们检查并验证它是否是导航到被路由到的组件的结束。在检查通过的这个阶段,应用程序已经导航到路由,现在我们可以安全地获取对 FramePage 的引用并删除操作栏。

Nativescript 有一个名为 topMost() 的函数,它允许我们获取对显示的 FramePage 的引用。根据他们的代码定义:获取帧堆栈中最顶层的帧。一个应用程序通常会有一个框架实例。多个框架处理嵌套(分层)导航场景。

因此,使用它我们可以轻松获得对当前正在显示的帧的 Page 的引用。现在我们已经显示了框架,我们只需将 actionBarVisibility 设置为 false;

import { Component } from '@angular/core';
import { Page } from 'tns-core-modules/ui/page';
import { Router, NavigationEnd } from '@angular/router';
import { topmost } from 'tns-core-modules/ui/frame/frame';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  constructor(private _Router: Router, private page: Page) {

  }

  ngOnInit(): void {

    this._Router.events.subscribe((ev) => {
      if (ev instanceof NavigationEnd) {
        const rootFrame = topmost();
        rootFrame.actionBarVisibility = 'never';
      }
    });
  }
}

您可以简单地在您的 page-router-outlet 上将 actionBarVisibility 设置为 never

<page-router-outlet actionBarVisibility="never"></page-router-outlet>