javascript - 使用 ng-if 时不显示 ionic View 标题

标签 javascript css angularjs ionic-framework

我正在为应用程序制作介绍屏幕。此屏幕(3 张幻灯片)仅在新用户时出现。所以我这样做的方式是:

  1. 默认路线总是转到这个介绍屏幕

  2. 在介绍屏幕 Controller 中,检查 (cookie) 以查看用户之前是否看过此屏幕。取决于此,切换 $scope.showIntro。然后执行 $state.go() 到下一个主应用屏幕。

  3. 在简介 View 中,使用 ng-if="showIntro"。因此,如果 $scope.showIntro == false,则 DOM 为空。

这里是棘手的部分:

  1. 没有办法检查用户是否已经看到这个屏幕,因为我正在使用 $localStorage 并且当我创建路由时它不存在于 app() 中.这就是为什么我必须在 Controller 中执行此检查逻辑。

  2. 我不得不使用 ng-if,因为如果我使用 ng-show,它太慢了,用户会在开始之前看到一闪而过的介绍屏幕路由到主屏幕。

问题:

如果我在 ion-view 组件上使用 ng-if,一旦 DOM 注入(inject) View ,标题就不会刷新再次。 这是为什么以及如何解决这个问题?也许有什么方法可以重新运行摘要?

代码 http://codepen.io/hawkphil/pen/jPLqge

angular.module('ionicApp', ['ionic'])
    
.config(function($stateProvider, $urlRouterProvider) {
    
$stateProvider
      .state('intro', {
        url: '/',
        templateUrl: 'templates/intro.html',
        controller: 'IntroCtrl'
      })
      .state('main', {
        url: '/main',
        templateUrl: 'templates/main.html',
        controller: 'MainCtrl'
      });
    
      $urlRouterProvider.otherwise("/");
    
    })
    
    .controller('IntroCtrl', function($scope, $state, $ionicSlideBoxDelegate) {
      $scope.title = "<b>CUSTOM</b> TITLE";
      $scope.showIntro = true;
      
      // Called to navigate to the main app
      $scope.startApp = function() {
        $state.go('main');
      };
      $scope.next = function() {
        $ionicSlideBoxDelegate.next();
      };
      $scope.previous = function() {
        $ionicSlideBoxDelegate.previous();
      };
    
      // Called each time the slide changes
      $scope.slideChanged = function(index) {
        $scope.slideIndex = index;
      };
    })
    
    .controller('MainCtrl', function($scope, $state) {
      console.log('MainCtrl');
      
      $scope.toIntro = function(){
        $state.go('intro');
      }
    });
    body {
      cursor: url('http://ionicframework.com/img/finger.png'), auto;
    }
    .slider {
      height: 100%;
    }
    .slider-slide {
      padding-top: 80px;
      color: #000;
      background-color: #fff;
      text-align: center;
    
      font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; 
      font-weight: 300;
    }
    
    #logo {
      margin: 30px 0px;
    }
    
    #list {
      width: 170px;
      margin: 30px auto;
      font-size: 20px;
    }
    #list ol {
      margin-top: 30px;
    }
    #list ol li {
      text-align: left;
      list-style: decimal;
      margin: 10px 0px;
    }
    
    .button.ng-hide{
      display:none;
    }
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
        <title>Ionic App</title>
    
        <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
        <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
      </head>
    
      <body ng-app="ionicApp">
    
        <ion-nav-bar class="bar-light">
            <ion-nav-back-button>
            </ion-nav-back-button>
        </ion-nav-bar>
    
        <ion-nav-view></ion-nav-view>
    
    
        <script id="templates/intro.html" type="text/ng-template"> 
          <ion-view view-title="{{ title }}" ng-if="showIntro">
            <ion-nav-buttons side="left">
              <button class="button button-positive button-clear no-animation"
                      ng-click="startApp()" ng-show="!slideIndex">
                Skip Intro
              </button>
              <button class="button button-positive button-clear no-animation"
                      ng-click="previous()" ng-show="slideIndex > 0">
                Previous Slide
              </button>
            </ion-nav-buttons>
            <ion-nav-buttons side="right"> 
              <button class="button button-positive button-clear no-animation"
                      ng-click="next()" ng-show="slideIndex != 2">
                Next
              </button>
              <button class="button button-positive button-clear no-animation"
                      ng-click="startApp()" ng-show="slideIndex == 2">
                Start using MyApp
              </button>
            </ion-nav-buttons>
            <ion-slide-box on-slide-changed="slideChanged(index)">
              <ion-slide>
                <h3>Thank you for choosing the Awesome App!</h3>
                <div id="logo">
                  <img src="http://code.ionicframework.com/assets/img/app_icon.png">
                </div>
                <p>
                  We've worked super hard to make you happy.
                </p>
                <p>
                  But if you are angry, too bad.
                </p>
              </ion-slide>
              <ion-slide>
                <h3>Using Awesome</h3>
                
                <div id="list">
                  <h5>Just three steps:</h5>
                  <ol>
                    <li>Be awesome</li>
                    <li>Stay awesome</li>
                    <li>There is no step 3</li>
                  </ol>
                </div>
              </ion-slide>
              <ion-slide>
                <h3>Any questions?</h3>
                <p>
                  Too bad!
                </p>
              </ion-slide>
            </ion-slide-box>
          </ion-view>
        </script>
    
        <script id="templates/main.html" type="text/ng-template">
          <ion-view hide-back-button="true" view-title="Awesome">
            <ion-content class="padding">
              <h1>Main app here</h1>
              <button class="button" ng-click="toIntro()">Do Tutorial Again</button>
            </ion-content>
          </ion-view>
        </script>
        
      </body>
    </html>

编辑 1

http://plnkr.co/edit/1FYr6GK6xMQjp9hA3N0M?p=preview

仅当介绍状态将 / 作为 url 路由时,下面的示例才有效。但是如果你输入 /intro 或其他 url,状态会一直迭代(截图)。

function config($stateProvider, $urlRouterProvider) {
  $stateProvider

    .state('intro', {
      url: '/intro',
      templateUrl: 'intro.html',
      controller: 'IntroCtrl',
      data: {
        isIntro: true
      },          
    })

    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      controller: 'MainCtrl',
      data: {
        isIntro: false
      },            
    });

    $urlRouterProvider.otherwise("/intro");
}

enter image description here

最佳答案

您可以在 View 开始之前使用 $stateChangeStart 检查您的本地存储:

$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
    console.log("$rootScope => $stateChangeStart => " + toState.name || '');

    if (toState.data && angular.isObject(toState.data)) {
    if (toState.data.isIntro && $localStorage.visitedIntro)
    {
        event.preventDefault();
        $state.go("main");
    } 
    }
});  

我所做的是为每个状态附加一个属性,这样我就可以确切地知道哪个是介绍(data.isIntro):

.state('intro', {
  url: '/',
  templateUrl: 'intro.html',
  controller: 'IntroCtrl',
  data: {
    isIntro: true
  },          
})

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  controller: 'MainCtrl',
  data: {
    isIntro: false
  },            
})

在更改 $stateChangeStart 之前,我检查本地存储是否设置了 visitedIntro 字段。如果已设置,我将转到主要路线。

在您的介绍 Controller 中,您可以设置 localstorage 属性的值:

.controller('IntroCtrl', function($scope, $state, $ionicSlideBoxDelegate, $localStorage) {

  $scope.title = "<b>CUSTOM</b> TITLE";
  $scope.showIntro = true;

  // Called to navigate to the main app
  $scope.startApp = function() {
    $state.go('main');
  };
  $scope.next = function() {
    $ionicSlideBoxDelegate.next();
  };
  $scope.previous = function() {
    $ionicSlideBoxDelegate.previous();
  };

  // Called each time the slide changes
  $scope.slideChanged = function(index) {
    $scope.slideIndex = index;
    if (index === 2)
    {
      $localStorage.visitedIntro = true;
    }
  };

});

当用户滑动并到达最后一张幻灯片时,我设置 $localStorage.visitedIntro = true

if (index === 2)
{
   $localStorage.visitedIntro = true;
}

如果您想了解它是如何工作的,请查看完整示例 here .

当然这只是一种选择。您还可以使用 ui-ruoter 的解析.

更新:

奇怪的迭代是 ui-ruoter 的一个已知问题。你可以查看这个question所以。

您可以通过这种方式更改 otherwise 并且它有效:

$urlRouterProvider.otherwise(function ($injector, $location) {
    var $state = $injector.get("$state");
    $state.go("intro");
}); 

我知道它不是很优雅,但至少它有效。
更新 plunker .

关于javascript - 使用 ng-if 时不显示 ionic View 标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30840007/

相关文章:

javascript - 使用生成器在 AngularJS 中使用 ng-repeat 进行迭代无法按预期工作

javascript - 监视嵌套在传递到 Angular 组件的多个对象中的更新

javascript - 这个网站如何自定义颜色?

javascript - 在javascript中使用正则表达式在字符串末尾找到匹配项

javascript - 如何使用javascript在struts2中将文件上传字段设置为空?

javascript - window.innerWidth 包括滚动条宽度

javascript - 为具有长标签的 md-input 显示星号图标

javascript - 如果不是 count===0,我希望通知框的背景变成红色...我该怎么做?

html - Bootstrap 布局嵌套?

json - 使用 AngularJS 获取 JSON 数据并在返回对象上添加方法