Onsen UI 组合导航(sliding-menu 带有标签栏和导航器)

Onsen UI combined navigation (sliding-menu with tabbar and navigator)

我正在升级我的第一个 PhoneGap 应用程序,其中包含几个需要单独页面的新功能。

我开始实施 sliding-menu,但很快就遇到了问题。

初始应用程序有一个 ons-navigator 负责应用程序的所有导航。

我有 2 个控制器:一个 LoginController 和一个 AppController。

我的 index.html 文件的结构如下所示:

<ons-sliding-menu main-page="navigator.html" menu-page="menu.html" side="left" max-slide-distance="250px" var="menu">
</ons-sliding-menu>

<ons-template id="menu.html">
  <ons-list>
    <ons-list-item modifier="tappable" onclick="menu.setMainPage('navigator.html', {closeMenu: true})">
      Home
    </ons-list-item>
    <ons-list-item modifier="tappable" onclick="menu.setMainPage('Page1.html', {closeMenu: true})">
      Page1
    </ons-list-item>
    <ons-list-item modifier="tappable" onclick="menu.setMainPage('Page2.html', {closeMenu: true})">
      Page2
    </ons-list-item>
  </ons-list>
</ons-template>

<ons-template id="navigator.html">
    <ons-navigator title="Navigator" var="myNavigator" page="main.html">

    </ons-navigator>
</ons-template>

这是页面的导航部分。

然后我有这样的页面:

<ons-template id="login.html">  
    <ons-page ng-controller="LoginController" id="login">
        <ons-toolbar>
            <div class="center">Log In</div>
        </ons-toolbar>
        <div class="login-form">
            <input type="text" class="text-input--underbar" placeholder="Username" ng-model="email">
            <input type="password" class="text-input--underbar" placeholder="Password" ng-model="password">
            <br><br>
            <ons-button modifier="large" class="login-button" ng-click="checkLogin(email,password)" > Log In</ons-button>
            <a href="" ng-click="openRegisterPage()">Don't have an account? Register now!</a>
        </div>
    </ons-page>
</ons-template>

<ons-template id="main.html">
    <ons-page id="main" >
        <ons-tabbar>
            <ons-tab active="true" page="SP1.html">
                <div class="tab">
                    <ons-icon icon="ion-calendar" class="tab-icon"></ons-icon>
                    <div class="tab-label">SP1</div>
                </div>
            </ons-tab>

            <ons-tab page="SP2.html">
                <div class="tab">
                    <ons-icon icon="ion-checkmark" class="tab-icon"></ons-icon>
                    <div class="tab-label">SP2</div>
                </div>
            </ons-tab>

            <ons-tab page="settings.html">
                <div class="tab">
                    <ons-icon icon="ion-gear-a" class="tab-icon"></ons-icon>
                    <div class="tab-label">Settings</div>
                </div>
            </ons-tab>
        </ons-tabbar>
    </ons-page>
</ons-template>

在 main.html 标签栏提到的页面中,我使用 AppController,在 login.html 我使用 LoginController .

当应用程序加载时,我有以下 ons.ready 函数:

ons.ready(function() {
    var storage = window.localStorage;
    if(storage.getItem("username")!=null) {
        if(storage.getItem("password")!=null) {
                myNavigator.resetToPage('main.html');
        }
    }
    else
    {
        myNavigator.resetToPage('login.html');
    }
});

我的第一个问题是,应用程序一开始就启动了 AppController,即使它不应该启动,所以如果缓存中没有保存的凭据,它仍然显示 main.html 页面一秒钟,然后转到 login.html。它做了一个不必要的循环,这可能是因为导航。一直没搞明白为什么,2个导航系统有点迷路

第二个问题是,我不能在 sliding-menu 的页面上包含 ons-back 按钮,因为它们出现一秒钟,然后被 header 重叠.

有什么办法可以清理导航系统,让 ons-sliding-menu 和 ons-navigation 相互配合?

另外:我是否应该在我倾向于使用 myNavigator.resetToPage('page.html') 函数的所有页面中包含一个 [ons-navigator var="myNavigator"]在?

这就是 Page1.html 的工作原理(即在 sliding-menu 中)

<ons-template id="Page1.html">
    <ons-navigator title="Navigator" var="myNavigator">
        <ons-page ng-controller="AppController" ng-init="ListLoad()" id="page1"> 

Page1.html 有一个项目列表,每个项目都可以点击并打开一个 Details.html 页面。

项目的 onclick 事件(它有一个简单的 myNavigator.resetToPage('details.html') 函数)在我将其添加到页面之前不起作用,但在我看来它不是对。

有什么方法可以弄清楚温泉的整个导航UI?

另外:有没有办法让底部的标签栏在所有页面上都可见?所以您可以从应用程序的任何页面转到 SP1.html 或 Settings.html?

尝试在一个应用程序中使用所有导航组件的道具。尽管您可能没有以正确的方式进行操作,但我想这就是您问这个问题的原因。

first problem is, that the application initiates the AppController

之所以这样做,是因为您已将其设置为最初加载 main.html

<ons-template id="navigator.html">
    <ons-navigator title="Navigator" var="myNavigator" page="main.html"></ons-navigator>
</ons-template>

如果您只删除 page 属性,一切都会好起来的。

The second problem is, that I cannot include ons-back buttons on the pages the sliding-menu has, because they appear for a second, and then they get overlapped by the header.

TBH 我不确定我是否能很好地掌握情况。我猜 header 是指 ons-toolbar 元素。如果它们重叠 - 为什么不将它们放在 ons-toolbar 中?其次,这似乎是某种 css 问题,为此你既没有提供 html 也没有提供 css 来重现,所以很难真正帮助你解决这个问题信息量。

所以我唯一可以建议的是right clickinspect element 并检查情况。你没有提到你使用的是哪个版本的 Onsen UI,但我猜 ons-backbutton 有可能隐藏自己,因为一些 Onsen 逻辑试图查看是否有以前的版本要返回的页面。

Any way, to clean up the navigational system, so the ons-sliding-menu and the ons-navigation work with eachother?

既然您看到使用多个组件管理导航很困难,我的建议是尽量限制自己在实际导航中使用较少的组件(最好是一个)。

我看到您似乎正在做的事情的方式 menu.setMainPage,这意味着当您这样做时,您将丢失当前页面导航器中的所有页面。但是,您似乎正试图稍后将导航器也放在其他页面中。

对于这种情况,一个更简单的解决方案是 - 让滑动菜单的主页只有一个带有导航器的页面。之后您可以调用 myNavigator.resetToPage 而不是调用 menu.setMainPage 并获得相同的结果。基本上,您仅使用滑动菜单来访问滑动菜单,然后使用导航器进行所有导航。

Also: Am I supposed to include an [ons-navigator var="myNavigator"] in all the pages that I tend to use the myNavigator.resetToPage('page.html') function on?

如果你想使用 myNavigator 你应该总是有一个导航器来访问。这就是为什么我的建议是将它放在 Page1Page2 等页面之外,然后将它们放在导航器内。 (你总是在sliding-menu中有navigator.html,只是把导航器的内容改成Page1Page2等)

Any ways of clarifying the whole navigation in the onsen UI?

基本上我们有几个导航组件。它们中的每一个都相当简单,提供一种或两种方法来在其中某处加载页面。唯一的例外是 ons-navigator。所以一般推荐的是使用导航器作为导航的主要组件,而其他像 sliding-menutabbar 只是为了它们带来的额外好处(滑动侧和标签栏按钮)。

如果您想拥有多个级别的导航,那完全由您决定 - 只要导航的结构是树状结构而不是网络(或意大利面条),它就应该没问题。通常,sheet 和一支笔是您在实施前决定此类导航的最好朋友。

ALSO: Is there a way, to have the bottom tabbar visible on all the pages? So you could go to SP1.html or Settings.html from ANY page in the app?

随着事情变得越来越简单,我们向 table 添加了一个复杂元素。

既然你想在应用程序的任何页面上都有标签栏,这意味着应用程序中的每个页面都应该在标签栏内。我猜你仍然想要你的 sliding-menu,所以我猜你应该有类似 ons-sliding-menu > ons-tabbar.

的东西

在这种情况下,我想到的解决方案是:

  1. 因为在您展示的代码中您只使用 myNavigator.resetToPage 而从不使用 pushPage 那么也许您可以删除一般的导航器。因此,也许您只能将 ons-sliding-menu > ons-tabbar 作为您的逻辑,然后通过标签栏进行所有导航。所以这意味着在你想要加载页面的所有地方使用类似 myTabbar.loadPage 的东西。

  2. 如果你想要,你可以有一个树型导航,你可以像以前一样做一些事情,但不同的是你想要使用像 pushPage 这样的页面你有导航器。因此,您将在设置标签栏的页面和使用导航器做一些事情之间做出选择。在此解决方案中,尽管每当您对标签栏执行操作时,您都会丢失导航堆栈。

  3. 同样不要使用标签栏进行导航,而是使用导航器。方法是:

    1. ons-sliding-menu > ons-tabbar 作为您的主要 html 结构
    2. 最初在标签栏内加载 navigator.html,就像您现在使用滑动菜单所做的那样。
    3. 不要为选项卡提供 activepage 属性,而是提供类似 ng-click="myNavigator.resetToPage('SP1.html')" 的属性。我想你也可以修改一些 类 如果你想让它们看起来被激活。

这就是我得到的几乎所有建议。

作为结论,我建议您尝试遵循 KISS principle