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

时间:2019-05-12 08:36:07

标签: angular android-actionbar nativescript angular-nativescript nativescript-codesharing

我的项目正在使用Angular + Nativescript代码共享项目为Web和移动设备(适用于Android和IOS)构建。

问题是试图删除整个应用程序的操作栏。我已经阅读了有关此问题的几篇文章,但是这些解决方案似乎都不起作用,或者至少最终不是一个很好的解决方案。

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

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

我还尝试了一种专门针对android的方法,以查看是否可以通过AndroidManifest.xml文件修复此问题,就像我通过更新android清单以删除操作栏来制作本机Android App一样。对于健全性测试,我还尝试通过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文件,并且必须在具有路由的每个组件中调用它。

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

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

2 个答案:

答案 0 :(得分:1)

您可以将actionBarVisibility本身上的never设置为page-router-outlet

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

答案 1 :(得分:0)

经过更多的研究和测试,我能够找到可以正常使用的解决方案。我还将解释为什么其他一些方法无法按预期工作的原因。

首先是<Page actionBarHidden="true">。根据我的研究和测试,这仅在您仅针对本机语言而不是作为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.htmlhome.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并管理另一项服务来运行仅适用于本机脚本的一段代码。

解决方案

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

本机脚本具有一个名为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';
      }
    });
  }
}