Adding Angular.js Modal gives Error: [$injector:unpr] - javascript

So I have an application and it's working great (MEAN stack), and I'm adding in the <script src="/lib/ui-bootstrap-custom-1.3.3.min.js"></script> and <script src="/lib/ui-bootstrap-custom-tpls-1.3.3.min.js"></script> so that I can use the modal.
The code will be below, but here are some explanations first. I've added angular.module('loc8rApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']); in my angular app declaration. And then in the controller I properly injected it via locationDetailCtrl.$inject = ['$routeParams', '$modal', 'loc8rData'];. I haven't declared an ng-controlleranywhere in the html, so I'm not really sure what the problem may be.
Lastly, a copy of the error:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.5/$injector/unpr?p0=%24modalProvider%20%3C-%20%24modal%20%3C-%20locationDetailCtrl
Below are 4 blocks of code. The first two are locationDetail.controller.js and locationDetail.view.html, the others are the app.js (angular app.js) and index.html.
locationDetail.controller.js
(function() {
angular
.module('loc8rApp')
.controller('locationDetailCtrl', locationDetailCtrl);
locationDetailCtrl.$inject = ['$routeParams', '$modal', 'loc8rData'];
function locationDetailCtrl($routeParams, $modal, loc8rData) {
var vm = this;
vm.locationid = $routeParams.locationid;
loc8rData.locationById(vm.locationid)
.success(function(data) {
vm.data = { location: data };
vm.pageHeader = {
title: vm.data.location.name
};
})
.error(function(e) {
console.log(e);
});
vm.popupReviewForm = function() {
alert("Let's add a review!");
};
}
})();
locationDetail.view.html
<navigation></navigation>
<div class="container">
<page-header content="vm.pageHeader"></page-header>
<div class="row">
<div class="col-xs-12 col-md-9">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p class="rating" rating-stars rating="vm.data.location.rating"></p>
<p>{{ vm.data.location.address }}</p>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Opening hours</h2>
</div>
<div class="panel-body">
<p ng-repeat="time in vm.data.location.openingTimes" ng-switch on="time.closed">
{{ time.days }} :
<span class="opening-time" ng-switch-when="true">closed</span>
<span class="opening-time" ng-switch-default>{{ time.opening + " - " + time.closing }}</span>
</p>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Facilities</h2>
</div>
<div class="panel-body">
<span class="label label-warning label-facility" ng-repeat="facility in vm.data.location.facilities">
<span class="glyphicon glyphicon-ok"></span>
{{ facility }}
</span>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 location-map">
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Location map</h2>
</div>
<div class="panel-body">
<img src="http://maps.googleapis.com/maps/api/staticmap?center={{ vm.data.location.coords[1] }},{{ vm.data.location.coords[0] }}&zoom=17&size=400x350&sensor=false&markers={{ vm.data.location.coords[1] }},{{ vm.data.location.coords[0] }}&scale=2" class="img-responsive img-rounded">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary review-panel">
<div class="panel-heading">
<a ng-click="vm.popupReviewForm()" class="btn btn-default pull-right">Add review</a>
<h2 class="panel-title">Customer reviews</h2>
</div>
<div class="panel-body review-container">
<div class="review" ng-repeat="review in vm.data.location.reviews | orderBy:'createdOn':true">
<div class="row">
<div class="well well-sm review-header">
<span class="rating" rating-stars rating="review.rating"></span>
<span class="reviewAuthor">{{ review.author }}</span>
<small class="reviewTimestamp">{{ review.createdOn | date : 'MMMM d yyyy' }}</small>
</div>
<div class="col-xs-12">
<p ng-bind-html="review.reviewText | addHtmlLineBreaks"></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-md-3">
<p class="lead">{{ vm.data.location.name }} is on Loc8r because it has accessible wifi and space to sit down with your laptop and get some work done.</p>
<p>If you've been and you like it - or if you don't - please leave a review to help other people just like you.</p>
</div>
</div>
<footer-generic></footer-generic>
</div>
app.js (angular app.js).
(function() {
angular.module('loc8rApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']);
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home/home.view.html',
controller: 'homeCtrl',
controllerAs: 'vm'
})
.when('/about', {
templateUrl: '/common/views/genericText.view.html',
controller: 'aboutCtrl',
controllerAs: 'vm'
})
.when('/location/:locationid', {
templateUrl: '/locationDetail/locationDetail.view.html',
controller: 'locationDetailCtrl',
controllerAs: 'vm'
})
.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
}
angular
.module('loc8rApp')
.config(['$routeProvider', '$locationProvider', config]);
})();
index.html
<!DOCTYPE html>
<html ng-app="loc8rApp">
<head>
<meta name="viewport" content="width=device-width", initial-scale="1.0">
<title>Loc8r</title>
<link rel="stylesheet" href="/bootstrap/css/amelia.bootstrap.css">
<link rel="stylesheet" href="/stylesheets/style.css">
<base href="/">
</head>
<body ng-view>
<script src="/angular/angular.min.js"></script>
<script src="/lib/angular-route.min.js"></script>
<script src="/lib/angular-sanitize.min.js"></script>
<script src="/lib/ui-bootstrap-custom-1.3.3.min.js"></script>
<script src="/lib/ui-bootstrap-custom-tpls-1.3.3.min.js"></script>
<script src="/angular/loc8r.min.js"></script>
<script src="/javascripts/jquery-1.12.2.min.js"></script>
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/javascripts/validation.js"></script>
</body>
</html>

Error tells you there is an unknown provider $modalProvider. That means you are injecting $modal and it isn't defined within the app.
The reason is that angular-ui-bootstrap now uses $uib prefix for services.
Try changing $modal to $uibModal and verify in angular-ui-bootstrap docs

Related

How to pass variable between states?

I'm new to ionic; I want to pass variables between two states, please guide me on how to do it.
I have setup a codepen example.
I want when items are left clicked (say item1, item2) move to view cart page and show id of clicked item.
Below is attached my code:
angular.module('ionicApp.controllers', [])
.controller('Tab1Ctrl', function($scope){
})
.controller('Tab2Ctrl', function($scope){
})
.controller('Tab3Ctrl', function($scope){
});
.btn-footer .button { margin: 0; }
.btn-footer .row { padding: 0; }
.btn-footer .col { padding: 0 5px; }
.img-box img { max-width: 100%; }
.p0 { padding: 0; }
.tabs-top-my .tab-nav.tabs { top: 0; }
.my-content-tabs > .row { height: 100%; }
.my-content-tabs .col-25,.my-content-tabs .col-20 { position:relative;}
.img-box {
height: 100%;
max-height: 100%;
position: absolute;
left: 0;
}
#maincontainer > div.scroll{padding-left:10px;}
.my-imgs-scroll { height: 100%; overflow:hidden !important; overflow-y:scroll !important; }
ion-scroll > div.scroll > img{ border-bottom:1px solid #eee;}
<!DOCTYPE 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 page</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
<script src="//code.jquery.com/jquery-1.11.3.js"></script>
<script src="//fabricjs.com/lib/fabric_with_gestures.js"></script>
</head>
<body ng-controller="HomeTabCtrl">
<ion-side-menus>
<ion-side-menu-content>
<ion-nav-view animation="slide-left-right"> </ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="right">
<div class="list">
<a class="item item-icon-left" href="#"><i class="icon ion-email"></i> Check mail</a>
<a class="item item-icon-left" href="#"> <i class="icon ion-chatbubble-working"></i>Call Ma</a>
<a class="item item-icon-left" href="#"> <i class="icon ion-mic-a"></i> Record album</a>
<a class="item item-icon-left" href="#"> <i class="icon ion-person-stalker"></i> Friends</a>
</div>
</ion-side-menu>
</ion-side-menus>
<script id="templates/tabs.html" type="text/ng-template">
<ion-tabs class="tabs-striped tabs-positive tabs-top tabs-top-my tabs-icon-only" animation="fade-in-out">
<ion-tab title="tab1" icon="ion-home" href="#/tab/tab1">
<ion-nav-view name="tab1-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="tab2" icon="ion-home" href="#/tab/tab2">
<ion-nav-view name="tab2-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="tab3" icon="ion-home" ui-sref="tabs.tab3">
<ion-nav-view name="tab3-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="tab4" icon="ion-home" ui-sref="tabs.tab4">
<ion-nav-view name="tab4-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="tab5" icon="ion-home" ui-sref="tabs.tab5">
<ion-nav-view name="tab5-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="tab6" icon="ion-android-apps" ng-click="toggleRightSideMenu()" ui-sref="tabs.tab6">
<ion-nav-view name="tab6-tab"></ion-nav-view>
</ion-tab>
</ion-tabs>
<ion-footer-bar class="bar-footer btn-footer bar-light">
<div class="row">
<div class="col">
<button class="button button-block button-positive" ng-click='next()'> View cart Page </button>
</div>
<div class="col">
<button class="button button-block button-calm"> View checkout page </button>
</div>
</div>
</ion-footer-bar>
</script>
<script id="templates/tab1.html" type="text/ng-template">
<ion-view view-title="tab1">
<div class="my-content-tabs scroll-content ionic-scroll has-header has-footer has-tabs-mytop">
<div class="row p0">
<div class="col col-25 p0">
<div class="img-box">
<ion-scroll zooming="false" direction="y" class="my-imgs-scroll" id="maincontainer">
<div id="1" style="height=:40px"> Item 1</div>
<hr/>
<div id="2" style="height=:40px"> Item 2</div>
<hr/>
<div id="3" style="height=:40px"> Item 3</div>
</ion-scroll>
</div>
</div>
<div class="col col-50" id="canvascontainer">
tab 1
</div>
<div class="col col-25 p0">
<div class="img-box">
<ion-scroll zooming="false" direction="y" class="my-imgs-scroll" id="maincontainer1">
</ion-scroll>
</div>
</div>
</div>
</div>
</ion-view>
</script>
<script id="templates/tab2.html" type="text/ng-template">
<ion-view view-title="tab2">
<div class="my-content-tabs scroll-content ionic-scroll has-header has-footer has-tabs-mytop">
<div class="row p0">
<div class="col col-25 p0">
<div class="img-box">
<ion-scroll zooming="false" direction="y" class="my-imgs-scroll" id="maincontainer">
</ion-scroll>
</div>
</div>
<div class="col col-50" id="canvascontainer">
tab 2
</div>
<div class="col col-25 p0">
<div class="img-box">
<ion-scroll zooming="false" direction="y" class="my-imgs-scroll" id="maincontainer1">
</ion-scroll>
</div>
</div>
</div>
</div>
</ion-view>
</script>
<script id="templates/tab3.html" type="text/ng-template">
<ion-view view-title="tab3">
<div class="my-content-tabs scroll-content ionic-scroll has-header has-footer has-tabs-mytop">
<div class="row p0">
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
<div class="col col-50"> <canvas id="canvas3"></canvas> </div>
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
</div>
</div>
</ion-view>
</script>
<script id="templates/tab4.html" type="text/ng-template">
<ion-view view-title="tab4">
<div class="my-content-tabs scroll-content ionic-scroll has-header has-footer has-tabs-mytop">
<div class="row p0">
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
<div class="col col-50"> Coming Soon </div>
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
</div>
</div>
</ion-view>
</script>
<script id="templates/tab5.html" type="text/ng-template">
<ion-view view-title="tab5">
<div class="my-content-tabs scroll-content ionic-scroll has-header has-footer has-tabs-mytop">
<div class="row p0">
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
<div class="col col-50"> Coming Soon </div>
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
</div>
</div>
</ion-view>
</script>
<script id="templates/tab6.html" type="text/ng-template">
<ion-view view-title="tab6">
<div class="my-content-tabs scroll-content ionic-scroll has-header has-footer has-tabs-mytop">
<div class="row p0">
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
<div class="col col-50"> Coming Soon </div>
<div class="col col-25 p0">
<div class="img-box">
</div>
</div>
</div>
</div>
</ion-view>
</script>
<script id="templates/nav-stack.html" type="text/ng-template">
<ion-view view-title="Tab Nav Stack">
<ion-content class="padding">
<p><img src="http://ionicframework.com/img/diagrams/tabs-nav-stack.png" style="width:100%"></p>
</ion-content>
</ion-view>
</script>
<script id="templates/next.html" type="text/ng-template">
<ion-view view-title="View Cart" nav-bar-class="bar-balanced">
<ion-nav-bar class="bar-positive" align-title="center">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-content class="padding">
clicked id :
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
<a class="button icon ion-chevron-left" href="#/tab/facts"> Scientific Facts</a>
</p>
</ion-content>
</ion-view>
</script>
<script>
angular.module('ionicApp', ['ionic', 'ionicApp.controllers', 'ngAnimate']).config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
.state('tabs.tab1', {
url: "/tab1",
views: {
'tab1-tab': {
templateUrl: "templates/tab1.html",
controller: 'Tab1Ctrl'
}
}
})
.state('tabs.tab2', {
url: "/tab2",
views: {
'tab2-tab': {
templateUrl: "templates/tab2.html",
controller: 'Tab2Ctrl'
}
}
})
.state('tabs.tab3', {
url: "/tab3",
views: {
'tab3-tab': {
templateUrl: "templates/tab3.html",
controller:'Tab3Ctrl'
}
}
})
.state('tabs.tab4', {
url: "/tab4",
views: {
'tab4-tab': {
templateUrl: "templates/tab4.html"
}
}
})
.state('tabs.tab5', {
url: "/tab5",
views: {
'tab5-tab': {
templateUrl: "templates/tab5.html"
}
}
})
.state('next', {
url: "/next",
templateUrl: "templates/next.html",
controller: "NextController",
params: {
clickedid: null
}
})
$urlRouterProvider.otherwise("/tab/tab1");
})
.controller('HomeTabCtrl', function($scope, $ionicSideMenuDelegate, $state) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
};
$scope.toggleRightSideMenu = function() {
console.log('rigth open')
$ionicSideMenuDelegate.toggleRight();
};
console.log('HomeTabCtrl');
$scope.next = function(){
$state.transitionTo('next');
}
}).controller("NextController", function($scope){
$scope.showAlert = function(){ alert("I'm a modal window!") }
});
</script>
</body>
</html>
The simple way is to use $rootScope but will always reset when the page refreshes, since it's a single-page app.
You need to use something that persists client-side, such as a cookie or sessionStorage (as they both have an expiration time). For the cookies see $cookieStore: https://docs.angularjs.org/api/ngCookies/service/$cookieStore
How about this ?
http://codepen.io/anon/pen/YwjEBx
Note that i'm not technically passing variable between states.
Your sidepanel and details view belong to the same controller so I just have to set some variable on the scope controller to play with.
Here's the main change : an ng-repeat with objects on the side panel. Use of a button to be able to bind an ng-click event. A currentItem in the scope that hold the value of the currentItem to be shown in the details view. I only modified the template tab1.html and the tab1Ctrl nothing more.
.controller('Tab1Ctrl', function($scope){
$scope.items = [{label:'Item 1', details:'details 1'},{label:'Item 2',details:'details 2'}]
$scope.currentItem=null;
$scope.setCurrentItem = function(item){
$scope.currentItem = item;
}
})
<div ng-repeat="item in items">
<button id="$index" style="height=:40px" ng-click="setCurrentItem(item)">{{item.label}}</button><hr/>
</div>
You can work with $rootScope to sharing data between controllers. I use a lot.
See here a good example
Don't abuse the $rootScope to pass things between states. It's not meant for that. $rootScope is meant for global application level functionality.
Please read this solution: watched scope is empty after route change

excecute angular controller from foundation's reveal modal

I'm trying to load a form using foundation's reveal modal, i need to run a angular controller inside the form to enable the form submission using ajax and not the default post/refresh behaviour.
this is my main view:
<html lang="es" ng-app="crm">
<body>
<script>
var crmapp = angular.module('crm', ['ng.django.forms',"ui.select"]);
</script>
<a data-reveal-id="idmodal" class="fi-burst" data-reveal-ajax="true" href="/operador/clientes/saldos/anadir/13">Añadir Pago</a>
<div id="idmodal" class="reveal-modal" data-reveal aria-labelledby="modalTitle" aria-hidden="false">
</div>
</body>
and this is my form:
<div class="row" ng-controller="dummy">
<h2>Añadir Pago</h2>
<ng-form>
<label>Fecha de Cobro:</label>
<label>Valor:</label>
<div class="row">
<div class="columns small-offset-5 small-7">
<button class="buttons success round" ng-click="alert(5)">Añadir</button>
</div>
</div>
</ng-form>
</div>
<script>
crmapp.controller('dummy', function($scope) { $scope.greeting = 'Hola!';console.log("bye"); });
</script>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
any "regular" javascript code in the form is called, but the angular controller isnt working. what can i do?
Here is how to work with ng-click and controller:
JSFiddle
HTML:
<div ng-app="myApp">
<div class="row" ng-controller="dummy">
<h2>Añadir Pago</h2>
<ng-form>
<label>Fecha de Cobro:</label>
<label>Valor:</label>
<div class="row">
<div class="columns small-offset-5 small-7">
<button class="buttons success round" ng-click="greeting()">Añadir</button>
</div>
</div>
</ng-form>
</div>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
JS:
angular.module('myApp', [])
.controller('dummy', ['$scope', function ($scope) {
$scope.greeting = function () {
console.log("bye");
};
}]);

Angular routes for a detailed view, using Foundation

Problem
New to Angular and I'm using "Foundation for Apps: to help with building a business directory in Angular. I'm looking to create routes for a detailed view for each of the businesses, which would look like http://localhost:8080/nameofbusiness.
I've been reading the Angular docs and this example pretty much does exactly what I'm trying to do, I've tried using in a similar snippet (see below) into app.js, but it doesn't seem to be compiling correctly.
Github: https://github.com/onlyandrewn/angular
Snippet
phonecatApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
app.js
'use strict';
var myApp = angular.module('application', [
'ui.router',
'ngAnimate',
//foundation
'foundation',
'foundation.dynamicRouting',
'foundation.dynamicRouting.animations'
])
.config(config)
.run(run)
;
config.$inject = ['$urlRouterProvider', '$locationProvider'];
function config($urlProvider, $locationProvider) {
$urlProvider.otherwise('/');
$locationProvider.html5Mode({
enabled:false,
requireBase: false
});
$locationProvider.hashPrefix('!');
}
function run() {
FastClick.attach(document.body);
}
home.html (Main view of all the businesses)
---
name: home
url: /
---
<div ng-controller="MainCtrl">
<header>
<p class="sponsored" id="top">Sponsored by </p>
<img src="http://placehold.it/200x30" class="sponsors" alt="">
<h1>Business Directory</h1>
<div class="find">
<input type="search" placeholder="What are you looking for?" ng-model="query">
</div><!-- /.find -->
</header>
<div class="businesses">
<div class="storeIcon">
<img src="/assets/img/store.png" class="store" alt="">
</div><!-- /.storeIcon -->
<p class="number">Search {{businesses.length}} businesses in Brandon</p><button class="filter button">Filter by <i class="fa fa-chevron-down"></i></button>
<div class="options">
<div class="cat">
<div class="categories">
<div class="group">
<p class="name">Grade Level</p>
<div class="check">
<input type="radio" name=""><p>Auto</p>
<input type="checkbox" name=""><p>Restaurant</p>
<input type="checkbox" name=""><p>Other</p>
</div><!-- /.check -->
</div><!-- /.group -->
<div class="group">
<p class="name">School Type</p>
<div class="check">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div><!-- /.check -->
</div><!-- /.group -->
</div><!-- /.categories -->
</div><!-- /.cat -->
</div><!-- /.options -->
</div><!-- /.businesses -->
<div class="all">
<div class="business large-4.columns" data-ng-repeat="business in businesses | filter:query | orderBy:'name'" >
<div class="overlay">
<img src="http://placehold.it/300x300" class="storefront" alt="">
</div><!-- /.overlay -->
<div class="info">
<p class="name">{{business.name}}</p>
<p class="description">{{business.description}}</p>
<p class="address">{{business.address}}</p>
{{business.website}}
</div><!-- /.info -->
</div>
</div>
<footer>
<hr>
<i class="fa fa-twitter"></i>
<i class="fa fa-facebook"></i>
<div class="backContainer">
<p class="back">Back to top</p>
</div><!-- /.backContainer -->
</footer>
</div>
expanded.html (Detailed view of just one of the businesses)
---
name: expand
url: /:id
---
<div ng-controller="MainCtrl">
<p>This is the expanded view for each of the businesses</p>
</div>
You will need to define a parent view for your expanded template using the simplified built in plugin, then foundation for apps will use that to generate the proper $routeProvider's configuration. You can also use that same plugin to define a wrapper controller for it.
Your expanded.html file may look like this :
---
name: expand
url: /:id
parent: home
controller: EditCtrl
---
<p>This is the expanded view for each of the businesses</p>
<pre> {{$stateParams}}</pre>
now if /#!/home is the url to what you decided to be a parent page or product listing page, then /#!/home/nameofbusiness will take you to it's child page "expanded", and it will set the id value of $stateParams to "nameofbusiness" $stateParams -> {"id":"nameofbusiness"} which will be accessible directly in your expand template or within it's related controller if you need to build some logic on top of it.
You will find more details in Foundation for apps Dynamic Routing documentation

angularJS pass variable to ui.bootstrap template

In my view i have such code:
<script id="template/accordion/accordion.html" type="text/ng-template">
<div class="panel-group" data-ng-transclude></div>
</script>
<script id="template/accordion/accordion-group.html" type="text/ng-template">
<div class="panel panel-default">
<div class="panel-heading custom">
<h4 class="panel-title custom">
<a href accordion-transclude="heading" data-ng-click="toggleOpen();"><span>{{heading}}</span></a>
</h4>
</div>
<div class="panel-collapse" collapse="!isOpen">
<div class="panel-body" data-ng-transclude></div>
</div>
</div>
</script>
<script type="text/ng-template" id="nodes_renderer.html">
<accordion close-others="false">
<accordion-group>
<accordion-heading>
{{node.Title}}
</accordion-heading>
<div data-ng-bind-html="node.Text"></div>
<ol ui-tree-nodes="" data-ng-model="node.Childs">
<li data-ng-repeat="node in node.Childs" ui-tree-node data-ng-include="'nodes_renderer.html'">
</li>
</ol>
</accordion-group>
</accordion>
</script>
<div ui-tree="options">
<ol ui-tree-nodes data-ng-model="articles">
<li data-ng-repeat="node in articles" ui-tree-node data-ng-include="'nodes_renderer.html'"></li>
</ol>
</div>
is it real to get node.Options.length, when i try to render header here:
<div class="panel-heading">
<h4 class="panel-title">
<a href accordion-transclude="heading" data-ng-click="toggleOpen();" class="no-link"><span>{{heading}}</span></a>
</h4>
</div>
and then if my node.Options are higher then 0 i do ng-class...
how could i pass variable to non-my directive template?
also i must pass there whole node object, so that i could edit it etc...
Every directive lives within a scope. I had a similar case where I wrote a common pager directive that pulls its details from the Controller scope. My templates are externalized, but this does not affect the functionality.
Directive usage:
<div class="row" ng-controller="TableController">
<table-pager></table-pager>
</div>
Directive definition:
angular.module.directive('tablePager', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'templates/table-pager.html'
};
})
Controller:
angular.module.controller('TableController', function($scope, $log, $location) {
$scope.query = {};
$scope.limit = 20;
$scope.offset = 0;
$scope.currentPage = 0;
$scope.total = 0;
...
}
Template code of templates/table-pager.html (snippet):
<div class="row">
<div class="col-md-4">{{total}} Entries found</div>
<div class="col-md-4 col-pager">...</div>
</div>
You can read more about AngularJS custom directives at http://tutorials.jenkov.com/angularjs/custom-directives.html
HTH

AngularJS share session data between controllers of different partial views?

I'm new to AngularJS and i don't know whether i'm doing things here right. I have a welcome and a login page. I would like to be able to login on the login page and then be logged on any page of my application. I'm aware that localStorage or cookies would be better than the service to store session data, but i wanted to try this out. When I connect the user using my service in the login partial view, the session variables of the controllers aren't updated. Why?
I guess the issue is quite simple to fix and due to the fact that i missed something.
Thank you in advance for your time.
Harald
Here comes the code:
Template html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>Yahoo 2014 - Welcome</title>
<link rel="icon" type="image/png" href="img/favicon.png">
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/animations.css">
<link rel="stylesheet" href="css/template.css">
<script src="lib/jquery/jquery-1.10.2.js"></script>
</head>
<body ng-controller="AppCtrl">
<header>
<nav role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target=".navbar-collapse" class="navbar-toggle"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><img src="img/logo.png" alt="Yahoo logo" class="img-responsive navbar-brand"/>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>Groupe</li>
<li>Services</li>
<li>Logiciels</li>
<li>Secteurs</li>
<li>Rejoignez-nous</li>
<li>Investisseurs</li>
<li>English version</li>
<li ng-hide="connected" >Login</li>
<li ng-hide="!connected"> </li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</header>
<div ng-view></div>
{{connected}}
{{username}}
<footer>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12">
<ul class="nav navbar-nav">
<li>Mentions légales</li>
<li>Plan du site</li>
<li>Contacter l'administrateur</li>
</ul>
</div>
</div>
<div class="row">
<div class="col xs-4 col-sm-4 col-md-4 col-lg-4">
<p>© Copyright Yahoo 2014</p>
</div>
</div>
</div>
</nav>
</footer>
<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>
-->
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-route/angular-route.js"></script>
<script src="lib/angular/angular-animate.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="lib/bootstrap/bootstrap.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
Index.html partial view
<div id="content">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12"><a id="bannerlink" href="http://www.yahoo.com"><img id="bannerimage" src="img/slider-mobile1.jpg" alt="Banner image" class="img-responsive"></a></div>
</div>
<div class="row">
<div class="articles" ng-repeat="article in articles">
<div class="col xs-4 col-sm-4 col-md-4 col-lg-4">
<h3>{{article.title}}</h3>
<p>{{article.content}}</p>
</div>
</div>
</div>
</div>
</div>
Login html partial view:
<div id="content" ng-controller="LoginCtrl">
<form name="login" action="#" ng-submit="login()">
<table>
<tr>
<td>
<p>Nickname</p>
</td>
<td>
<input type="text" name="nickname" ng-model="nickname" required>
</td>
</tr>
<tr>
<td>
<p>Password</p>
</td>
<td>
<input type="password" name="password" ng-model="password" required>
</td>
</tr>
</table>
<input type="submit" id="submit" value="Submit">
</form>
</div>
App.js:
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/index', {templateUrl: 'partials/index.html', controller: 'IndexCtrl'});
$routeProvider.when('/group', {templateUrl: 'partials/group.html', controller: 'GroupCtrl'});
$routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'LoginCtrl'});
$routeProvider.otherwise({redirectTo: '/index'});
}]);
Controllers:
'use strict';
/* Controllers */
angular.module('myApp.controllers', [])
.controller('AppCtrl', ['$scope', 'Session', function(scope, Session) {
scope.connected=Session.isConnected();
scope.username="Harald";
scope.login = Session.connect();
scope.disconnect = Session.disconnect();
scope.$watch('connected', function(){
alert("Connected changed!");
});
}])
.controller('IndexCtrl', [ '$scope', 'Article', function(scope, Article) {
scope.articles = Article.query();
}])
.controller('GroupCtrl', [function() {
}])
.controller('LoginCtrl', [ '$scope', 'Session', function(scope, Session) {
scope.connected=Session.isConnected();
scope.login = Session.connect();
scope.disconnect = Session.disconnect();
}]);
Services:
'use strict';
/* Services */
// Demonstrate how to register services
// In this case it is a simple value service.
var myAppServices = angular.module('myApp.services', ['ngResource']).
value('version', '0.1');
myAppServices
.factory('Article', ['$resource',
function(resource){
return resource('articles/:articleId.json', {}, {
query: {method:'GET', params:{articleId:'articles'}, isArray:true}
});
}])
.factory('Session', function() {
var connected = false;
var nickname = "unknown";
return{
isConnected : function() {
return connected;
},
getNickname : function() {
return nickname;
},
connect : function() {
connected = true;
window.alert("Connected service!");
},
disconnect : function() {
connected = false;
}
}
});
isConnected() returns a boolean. When you change connected in your service, you assign it a new value, but that won't affect $scope.connected
You could keep the two in sync by using a watch function:
scope.$watch(Session.isConnected, function(connected){
$scope.connected = connected;
});
From what i understand and correct me if i am wrong. you want to store state in a service and check that state when route changes to see if the user is logged in or not without the use of cookies or local storage. However storing user state in just a service will not work as if the user hits refresh button the service will be undefined and no longer valid.

Categories

Resources