1

我的项目正在使用 Angular + Nativescript 代码共享项目来构建 Web 以及 Android 和 IOS 的移动设备。

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

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

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

我还尝试了一种专门针对 android 的方法,看看我是否可以通过AndroidManifest.xml文件修复这个问题,就像我通过更新 android 清单以移除操作栏来制作原生 Android 应用程序一样。对于健全性测试,我还尝试通过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.actionBarHidden并且rootFrame.actionBarVisibility = 'never'您可以在文件中调用它component.ts而无需创建component.tns.ts文件但是问题是现在您需要创建一个具有要调用的空函数,tns为实际逻辑创建该服务的文件,并且必须在每个具有路由的组件中调用它。

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

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

4

2 回答 2

5

您可以简单地设置actionBarVisibilityneverpage-router-outlet自己。

<page-router-outlet actionBarVisibility="never"></page-router-outlet>
于 2019-05-12T13:50:27.500 回答
0

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

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

现在,当我们开始编写 Nativescript 时,我们希望尽可能多地重用代码,包括我们的路由。在这种情况下,我们最终<page-router-outlet></page-router-outlet>会在我们的app.component.tns.html文件中使用。就像 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 组件,那么您需要this.page.actionBarHidden在 Home 组件中使用它。但是,为了在 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';
      }
    });
  }
}
于 2019-05-12T09:01:36.867 回答