我的项目正在使用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.actionBarHidden
和rootFrame.actionBarVisibility = 'never'
具有此逻辑的服务,您可以在component.ts
文件中调用它而无需创建一个component.tns.ts
文件,但是与此相关的问题是,现在您需要创建一个常规服务,该服务具有要调用的空函数,为实际逻辑创建该服务的tns
文件,并且必须在具有路由的每个组件中调用它。
如您所见,某些解决方案根本无法使用,而另一些解决方案则需要大量额外的代码和可维护性,尤其是随着应用程序的增长,它们并不是非常理想的解决方案。
我将继续研究这个问题,并且我相信对此必须有一个干净的解决方案。
答案 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.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
并管理另一项服务来运行仅适用于本机脚本的一段代码。
解决方案
这是我能解决的最简单的解决方案,它允许将操作栏的处理放在一个位置,以便随时更改。解决方案是使用Angular的Router
。我们在ngOnInit
中所做的是我们订阅了路由器的事件。然后,当路由器事件触发时,我们检查并验证是否是导航到要路由到的组件的结尾。在此阶段,当支票通过时,应用程序已经导航到了路线,对于我们来说,现在可以安全地引用该Frame
或Page
并删除操作栏。
本机脚本具有一个名为topMost()
的功能,该功能使我们可以引用所显示的Frame
或Page
。根据其代码定义:获取帧堆栈中最顶层的帧。一个应用程序通常会有一个框架实例。多个框架可处理嵌套(分层)导航方案。
因此,使用此方法,我们可以轻松获取对当前显示的帧的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';
}
});
}
}