我正在为应用程序制作介绍屏幕。此屏幕(3 张幻灯片)仅在新用户时出现。所以我这样做的方式是:
默认路线总是转到这个介绍屏幕
在介绍屏幕 Controller 中,检查 (cookie) 以查看用户之前是否看过此屏幕。取决于此,切换
$scope.showIntro
。然后执行$state.go()
到下一个主应用屏幕。在简介 View 中,使用
ng-if="showIntro"
。因此,如果 $scope.showIntro == false,则 DOM 为空。
这里是棘手的部分:
没有办法检查用户是否已经看到这个屏幕,因为我正在使用
$localStorage
并且当我创建路由时它不存在于 app() 中.这就是为什么我必须在 Controller 中执行此检查逻辑。我不得不使用
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");
}
最佳答案
您可以在 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/