I am doing an intro screen for an app. This screen (3 slides) only appears when on new user. So the way I do it is:
Default route is always going to this intro screen
From the intro screen controller, check (cookie) to see if the user has seen this screen before. The depending on that, toggle
$scope.showIntro
. Then do$state.go()
to next main app screen.In the intro view, use
ng-if="showIntro"
. So if $scope.showIntro == false, the DOM is blank.
Here are the tricky parts:
There is no way to check for whether the user has seen this screen or not because I am using
$localStorage
and it doesn't exist in app() when I create the route. That's why I have to do this check logic in the controller.I had to use
ng-if
because if I useng-show
, it's too slow and the user will see a flash of intro screens before being routed to main screen.
THE PROBLEM:
If I use ng-if
on ion-view
component, the title does not get refreshed once the DOM is injected into the view again. Why is that and how to fix this problem? Maybe some way to re-run digest?
Code 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>
EDIT 1
http://plnkr.co/edit/1FYr6GK6xMQjp9hA3N0M?p=preview
Below answer's example works only if the intro state has /
as the url route. But if you put /intro
or other url, the state kept iterating (screenshot).
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");
}