UI-Router Multiple Views Single Controller not work - angularjs

I would like to use one controller defined in views, but the $scope does not define anything. Is there a way to do this? Please share a simple example in order to understand.
I have this index.html
<body ng-app="ehc">
<h1>{{home}}+{{a}}+{{b}}</h1>
<ion-side-menus enable-menu-with-back-views="false" delegate-handle="left">
<!-- Left menu -->
<ion-side-menu side="left" is-enabled="true">
<ion-header-bar class="bar-stable">AAA</ion-header-bar>
<ion-content>
<div class="list">
<div class="item item-divider">
Candy Bars
</div>
</div>
</ion-content>
</ion-side-menu>
<ion-side-menu-content edge-drag-threshold="true" drag-content="true">
<!-- Main content, usually <ion-nav-view> -->
<ion-nav-bar class="bar-positive" >
<ion-nav-title>
<h2>hello world title *{{home}}*</h2>
</ion-nav-title>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-view>
<ion-content class="has-header">
<div class="row">
<div class="col-50">
<div ui-view="a"></div>
</div>
<div class="col-50">
<div ui-view="b"></div>
</div>
</div>
</ion-content>
</ion-view>
</ion-side-menu-content>
<script type="text/ng-template" id="templates/a.html">
<ion-view>
<ion-content class="has-header">
**{{a}}**
</ion-content>
</ion-view>
</script>
<script type="text/ng-template" id="templates/b.html">
<ion-view>
<ion-content class="has-header">
**{{b}}**
</ion-content>
</ion-view>
</script>
</body>
<script src="js/app.js"></script>
And this is my model definition app.js
var app = angular.module("ehc", ["ionic"])
.config(function ($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('Home', {
url: '/',
controller: "HomeCtrl",
//template:"<ion-header-bar></ion-header-bar><ion-content><h1>hello dal AngularJs</h1></ion-content>",
views: {
"a": {
templateUrl: 'templates/a.html'
},
"b": {
templateUrl: 'templates/b.html'
}
}
});
}).controller("HomeCtrl", ["$scope", "$ionicSideMenuDelegate",
"$routeParams", "config", "$q", "$http"], function ($scope, $ionicSideMenuDelegate, $routeParams, config, $q, $http) {
$scope.toggleLeft = function () {
$ionicSideMenuDelegate.toggleLeft();
};
//carico le lingue e il menu
console.log("AAAAAAAAAAAA");
$scope.home = "Pippo";
$scope.a="XAX";
$scope.b="XBX";
})
console is empty and also the scope in html template. Please if you have the solution, use very simple example.
I've read here and I thought it worked Rakrap Jaknap answered on 2015-04-17 08:01

Very similar issue: Why controller does not work in UI-router of angularjs?
The point here is:
Controller always belongs to View, never to state.
Other words, to use same type of controller (but two instances for each view), we have to do that kind of declaration:
$stateProvider.state('Home', {
url: '/',
// instead of this
//controller: "HomeCtrl",
views: {
"a": {
templateUrl: 'templates/a.html',
controller: "HomeCtrl", // we need this
},
"b": {
templateUrl: 'templates/b.html',
controller: "HomeCtrl", // and also this
}
}
});
In case, we want to share some stuff among many views, we need different technique than "same controller". See:
How do I share $scope data between states in angularjs ui-router?
Another insight, could be covered here:
scope and controller instantiation with ui router
And including typescript, there is a detailed description and example how all views/states could target some common RootModel
Angular Digest cycle being ran but ng-bind value not updating

Related

Angular - Add compiled html snippet, dynamicly to a directive, before the directive gets compiled

I'm trying to add a directive into another directive dynamically in Ionic for Example:
<ion-nav-buttons side="right">
// If the page has my-directive, add here a my-button to control it
</ion-nav-buttons>
I'm trying to do this from another directive, which is more deeper.
my try on codepen.
Background:
I want, that if I use my-directive somewhere deeper, that my-directive adds dynamically a button to the navbar, which can control the my-directive.
Edit: I tried it again codepen 2, but there are still some issues:
When going to a page where the directive isn't present, the button should also be removed.
The button only appears, when you directly start on the page where the directive is. If you start somewhere else and navigate to it, it doesn't work.
Somewhere I have a $timeout wich waits 0 milliseconds, doesn't work without, but why should this be necessary.
You could create a directive for your navbar and pass the markup to the directive's isoltated scope.
Passing can be done with $rootScope or with a factory. I would prefer a factory but in the demo I've used the rootScope for passing.
I also don't like the scope passing in the demo. It's working but I think it would be better to store the handler in a factory too. The factory can then manage the creation of the icon in navbar and the event handler for the action you need for the button.
Please have a look at the following demo or in this codepen.
angular.module('ionicApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$ionicConfigProvider.views.swipeBackEnabled(false);
$ionicConfigProvider.views.maxCache(0);
$stateProvider
.state('eventmenu', {
url: "/event",
abstract: true,
templateUrl: "templates/event-menu.html"
})
.state('eventmenu.home', {
url: "/home",
views: {
'menuContent' :{
templateUrl: "templates/home.html"
}
}
})
.state('eventmenu.checkin', {
url: "/check-in",
views: {
'menuContent' :{
templateUrl: "templates/check-in.html",
controller: "CheckinCtrl"
}
}
})
.state('eventmenu.attendees', {
url: "/attendees",
views: {
'menuContent' :{
templateUrl: "templates/attendees.html",
controller: "AttendeesCtrl"
}
}
})
$urlRouterProvider.otherwise("/event/home");
})
.controller('MainCtrl', function($scope, $ionicSideMenuDelegate) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
};
})
.controller('CheckinCtrl', function($scope) {
$scope.$on('$ionicView.afterEnter', function() {
console.log('entered');
});
})
.controller('AttendeesCtrl', function($scope) {
})
.directive( 'dynNavbar', function($compile) {
return {
scope: {
optional: '='
},
template: '<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button><div class="dynButton"/>',
link: function(scope, element) {
scope.$watch('optional', function(){
var dynButton = scope.optional;
console.log(scope.optional, element, element[0].querySelector('.dynButton'), $compile(dynButton.html)(scope));
angular.element(element[0].querySelector('.dynButton')).replaceWith($compile(dynButton.html)(dynButton.scope));
});
}
}
})
.directive('test', function($compile) {
return {
restrict: 'E',
replace: true,
template: '<p ng-style="{color: styleFlag}">use this directive, with the button in the navbar</p>',
controller: function($scope, $rootScope) {
$rootScope.injectedButton = {html: '<a class="button button-icon icon ion-eye" ng-click="cry()"></a>',
scope: $scope
};
var styleFlag = false;
$scope.cry = function () {
console.log('buhuhuhu');
styleFlag = !styleFlag; // change style just as example
$scope.styleFlag = styleFlag ? 'red': 'black';
//console.log(styleFlag, $scope.styleFlag);
};
},
link: function(scope, el, attrs){
// -----------------------------------
// ADD BUTTON IN NAVBAR
// -----------------------------------
//scope.$on('$ionicView.afterEnter', function(){
/* var nav = document.getElementsByClassName('nav-bar-block');
if (nav[0].getAttribute('nav-bar') == 'active' || nav[0].getAttribute('nav-bar') == 'entering') {
nav = angular.element(nav[0].getElementsByClassName('right-buttons')[0]);
}
if (nav[1] && nav[1].getAttribute('nav-bar') == 'active' || nav[1] && nav[1].getAttribute('nav-bar') == 'entering') {
nav = angular.element(nav[1].getElementsByClassName('right-buttons')[0]);
}
console.log(nav);
nav.append($compile('<a class="button button-icon icon ion-eye" ng-click="cry()"></a>')(scope));
// });
*/
// -----------------------------------
// FUNCTION FOR THE BUTTON
// -----------------------------------
/*scope.cry = function () {
console.log('buhuhuhu');
};*/
}
}
});
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Side Menus</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-controller="MainCtrl">
<ion-nav-view></ion-nav-view>
<script id="templates/event-menu.html" type="text/ng-template">
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
</ion-nav-buttons>
<ion-nav-buttons side="right">
<!--<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>-->
<dyn-navbar optional="injectedButton"/>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-assertive">
<h1 class="title">Left Menu</h1>
</ion-header-bar>
<ion-content>
<ul class="list">
<a href="#/event/check-in" class="item" menu-close>Check-in</a>
<a href="#/event/attendees" class="item" menu-close>Attendees</a>
</ul>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</script>
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Welcome">
<ion-content class="padding">
home: <test></test>
</ion-content>
</ion-view>
</script>
<script id="templates/check-in.html" type="text/ng-template">
<ion-view view-title="Event Check-in">
<ion-content>
checkin: <test></test>
</ion-content>
</ion-view>
</script>
<script id="templates/attendees.html" type="text/ng-template">
<ion-view view-title="Event Attendees">
<ion-content>
attendees: <test></test>
</ion-content>
</ion-view>
</script>
</body>
</html>

Ionic Showing multiple viewes in a single page

Im using Ionic to build an application.
Im new to Ionic and i would like some help in setting up my view.
my app contains an abstract main view which contains the main header
<script type="text/ng-template" id="main-view">
<ion-header-bar class='bar bar-header bar-stable' align-title="center">
<h3 class="title">Title</h3>
</ion-header-bar>
<ion-nav-view name="View-A"></ion-nav-view>
<ion-nav-view name="View-B"></ion-nav-view>
</script>
and another view which supposed to be like a split screen. basicly i`m trying to show 2 views on the same page (with different controllers)
this is my config:
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
// setup an abstract state for the tabs directive
.state('main', {
url: '/main',
abstract: true,
templateUrl: 'main-view'
}
})
.state('main.inner', {
url: '/inner',
views: {
'View-A': {
templateUrl: "View-A",
controller: 'ViewACtrl'
},
'View-B': {
templateUrl: 'View-B',
controller: 'ViewBCtrl'
}
}
});
$urlRouterProvider.otherwise('/main/inner');
})
The views look like this
<script type="text/ng-template" id="View-A">
<ion-view>
<-- DATA -->
</ion-view>
</script>
<script type="text/ng-template" id="View-B">
<ion-view>
<-- DATA -->
</ion-view>
</script>
The Problem is, that only the second view is shown.
what am i doing wrong?
Try to replace
<ion-nav-view name="View-A"></ion-nav-view>
<ion-nav-view name="View-B"></ion-nav-view>
with
<div ui-view="View-A"></div>
<div ui-view="View-B"></div>
EDIT
There is an option to use this library. Add 'ionicMultipleViews' to angular.module and it should work.

Angular view to Ionic view

What am I doing wrong? I've followed countless tutorials on Youtube/Google and yet it doesn't seem to be working.
I want to load games and when you click on one of them, it should give a detail view. This all worked fine in Angular only, but I wanted to try in Ionic for the animation.
Note: Following code is to display the list of games.
Index.html
<body ng-app="myApp">
<script id="list.html" type="text/ng-template">
<ion-nav-view></ion-nav-view>
</script>
</body>
Controller
var ctrl = angular.module('Controllers', []);
ctrl.controller('MainController', ['$scope', '$http', '$location', 'games', function($scope, $http, $location, games){
$scope.games = [];
$scope.games = games.all();
}]);
You can assume I get data in code above.
App config
app.config(['$stateProvider',function($stateProvider) {
$stateProvider
.state('list', {
url: "/",
templateUrl: 'templates/list.html',
controller: 'MainController'
})
}])
List.html
<ion-view view-title="Games">
<ion-refresher pulling-text="Refresh..." on-refresh="refresh()"></ion-refresher>
<ion-content>
<div class="game" ng-repeat="game in games.results" ng-click="checkDetail(game, $index)">
<!--<img ng-src="{{ game.image.screen_url }}" alt="{{ game.aliases }}" />-->
<h3>{{ game.name }}</h3>
</div>
</ion-content>
</ion-view>
Codepen
Here's a codepen I based it on
http://codepen.io/darrenahunter/pen/oDKid
You have to declare a ui-view to inject template from state.
Edit your index.html like that :
<body ng-app="myApp">
<div ui-view>
</div>
</body>
or
<body ng-app="myApp">
<ion-nav-view name="content"></ion-nav-view>
</body>
and edit your state like that
.state('statename', {
url: "/",
views: {
'content': {
templateUrl: 'yourTemplate.html',
controller: "yourCtrl"
}
}
}
that way you force to inject your view in that ion-nav-view.
The same way you can create
<div ui-view="content"></div>

Popup and ion-nav-view don't work togehter

I have newbie question.
I need some really basic AngularJS in my app. I made my popup work and then added ion-nav-view. Both elements works, but not simultaneously. Now ion-nav-view works perfect, but when i change
body ng-app="starter"
to
body ng-app="starter" ng-controller="PopupCtrl"
app turns into blank site.
It must be some small mistake but i can't find, where it is. Can anyone help me? My app.js:
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
angular.module('starter', ['ionic'])
.controller('PopupCtrl', function($scope, $ionicPopup, $timeout) {
$scope.showAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Alert',
template: 'Alert text'
});
};
});
angular.module('starter', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('list', {
url: '/1',
templateUrl: 'list.html'
})
.state('info', {
url: '/2',
templateUrl: 'info.html'
})
$urlRouterProvider.otherwise("/1");
})
EDIT:
Body section of index.html:
<body ng-app="starter" ng-controller="PopupCtrl">
<ion-nav-bar class="bar-positive" align-title="center">
</ion-nav-bar>
<ion-nav-view class="slide-left-right"></ion-nav-view>
<script id="list.html" type="text/ng-template">
<ion-view title="title">
<ion-nav-buttons side="right">
<button class="button button-icon icon ion-android-locate" ng-click="showAlert()"></button>
</ion-nav-buttons>
<ion-content>
<div class="list">
<a class="item item-thumbnail-left" href="#">
<img src="cover.jpg">
<h2>Pretty Hate Machine</h2>
<p>Nine Inch Nails</p>
</a>
<a class="item" ui-sref="info">
<p>Żeby uzyskać pomoc, dotknij to pole.</p>
</a>
</div>
</ion-content>
</ion-view>
</script>
<script id="info.html" type="text/ng-template">
<ion-view title="Informacje">
<ion-content class="padding">
<div class="card">
<div class="item item-text-wrap">
<img src="img/logo.png" style="width: 100%">
</div>
</div>
</ion-content>
</ion-view>
</script>
</body>
Module should be get injected with dependency while you are creating it like here you did angular.module('starter', ['ionic']) but while consuming it you need to use angular.module('starter'), As module is already created. If you do the same thing again then previously registered component of that module will get flushed.
Like in your code you need to use angular.module('starter') while defining controller & config
Code
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
//code here
})
angular.module('starter')//<-- change here
.controller('PopupCtrl', function($scope, $ionicPopup, $timeout) {
//code here
});
angular.module('starter') //<-- change here
.config(function($stateProvider, $urlRouterProvider) {
//code here
})

Using Ionic tabs on a side menu page

I am new to the ionic framework and was trying to achieve using the tabs component on a side menu page which works fine but the navigation animations from page to page with the slide-left-right animation declaration don't work.
for e.g.
there is a base state (app) which holds the side menu code
.state('app', {
url: '/app',
abstract: true,
templateUrl: "templates/menu.html",
controller: "appController"
})
and its loaded into
<body>
<ion-nav-view animation="slide-left-right"></ion-nav-view>
...
side menu pages are loaded with the parent (app.pageOne, app.pageTwo etc)
Login and register pages are loaded at the root so is no need to include a side menu (login, register etc)
I created a tabs template to use on a side menu page with another base state for the tabs
.state('app.tabs', {
url: '/tab',
abstract: true,
views: {
'menuContent' :{
templateUrl: "templates/tabs.html"
}
}
})
and is loaded in the side menu view
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view>
Now if I have a page 'app.pageOne' and navigate to 'app.pageTwo' the slide animations works as expected.
But if I'm on a tab page 'app.tabs.home' and click a link to go to 'app.pageTwo' the nav-bar don't update nor is there any animation transition.
I'm aware it looks like a parent child issue but I just can't solve it, any ideas?
state are as follows eg
login
register
app ____page1
|____page2
|____Tabs
|____Home
|____Contact etc
page1 animation to page2 works fine
Home to page2 doesn't animate (It just loads straight away)
Hope that makes more sense.
check this url http://codepen.io/calendee/pen/JdtuG?editors=101
it works for me :)
html
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic Template</title>
<link href="http://code.ionicframework.com/0.9.27/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/0.9.27/js/ionic.bundle.min.js"></script>
</head>
<body>
<!-- ALL VIEW STATES LOADED IN HERE -->
<ion-nav-view></ion-nav-view>
<script id="entry.html" type="text/ng-template">
<ion-nav-bar animation="nav-title-slide-ios7"
type="bar-positive"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back">
</ion-nav-bar>
<ion-view title="{{navTitle}}" class="bubble-background">
<ion-content has-header="true" padding="true">
<h1>Entry Page!</h1>
<a class="button button-positive" ng-click="signIn()" ui-sref="main.home">Sign In</a>
</ion-content>
</ion-view>
</script>
<script id="tabs.html" type="text/ng-template">
<ion-view title="{{navTitle}}" left-buttons="leftButtons">
<ion-tabs tabs-type="tabs-icon-only">
<ion-tab title="Tab 1" icon-on="ion-ios7-filing" icon-off="ion-ios7-filing-outline">
<ion-content has-header="true" padding="true">
<h2>Tab 1 Content</h2>
</ion-content>
</ion-tab>
<ion-tab title="Tab 2" icon-on="ion-ios7-filing" icon-off="ion-ios7-filing-outline">
<ion-content has-header="true" padding="true">
<h2>Tab 2 Content</h2>
</ion-content>
</ion-tab>
<ion-tab title="Tab 3" icon-on="ion-ios7-filing" icon-off="ion-ios7-filing-outline">
<ion-content has-header="true" padding="true">
<h2>Tab 3 Content</h2>
</ion-content>
</ion-tab>
</ion-tabs>
</ion-view>
</script>
<script id="mainContainer.html" type="text/ng-template">
<ion-side-menus>
<ion-pane ion-side-menu-content>
<ion-nav-bar type="bar-positive"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back"
animation="nav-title-slide-ios7"
>
</ion-nav-bar>
<ion-nav-view name="main"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<header class="bar bar-header bar-assertive">
<div class="title">Side Menu</div>
</header>
<ion-content has-header="true">
<ul class="list">
<a ui-sref="entry" class="item">Back To Entry Page</a>
<a ui-sref="main.home" class="item" ng-click="toggleMenu()">Home</a>
<a ui-sref="main.tabs" class="item" ng-click="toggleMenu()">Tabs</a>
</ul>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</script>
<script id="home.html" type="text/ng-template">
<ion-view title="{{navTitle}}" left-buttons="leftButtons">
<ion-content has-header="true" padding="true">
<h1>Home Page!</h1>
<a ui-sref="main.info" class="button button-positive">Info</a>
</ion-content>
</ion-view>
</script>
<script id="info.html" type="text/ng-template">
<ion-view title="{{navTitle}}" left-buttons="leftButtons">
<ion-content has-header="true" padding="true">
<h1>Info Page!</h1>
</ion-content>
</ion-view>
</script>
</body>
</html>
javascript
angular.module('ionicApp', ['ionic'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('entry', {
url : '/entry',
templateUrl : 'entry.html',
controller : 'EntryPageController'
})
.state('main', {
url : '/main',
templateUrl : 'mainContainer.html',
abstract : true,
controller : 'MainController'
})
.state('main.home', {
url: '/home',
views: {
'main': {
templateUrl: 'home.html',
controller : 'HomePageController'
}
}
})
.state('main.info', {
url: '/info',
views: {
'main': {
templateUrl: 'info.html',
controller : 'InfoPageController'
}
}
})
.state('main.tabs', {
url: '/tabs',
views: {
'main': {
templateUrl: 'tabs.html',
controller : 'TabsPageController'
}
}
})
$urlRouterProvider.otherwise('/entry');
}])
.controller('MainController', [ '$scope', function($scope) {
$scope.toggleMenu = function() {
$scope.sideMenuController.toggleLeft();
}
}])
.controller('EntryPageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Entry Page';
$scope.signIn = function() {
$state.go('main.home');
}
}])
.controller('HomePageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Home Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function(e) {
$scope.toggleMenu();
}
}];
}])
.controller('InfoPageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Info Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function(e) {
$scope.toggleMenu();
}
}];
}])
.controller('TabsPageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Tab Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function(e) {
$scope.toggleMenu();
}
}];
}])
it took some tweaks but finally worked on my scenario

Resources