I use ng-show to show or hide navigator.
In index.html :
<div class="container" ng-show="vm.error" nav></div>
In app.js
var siteApp = angular.module('siteApp', ['ngRoute']);
siteApp.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
controllerAs: 'vm',
templateUrl: '/home.html'
})
.when('/404', {
controller: 'ErrorController',
controllerAs: 'vm',
templateUrl: '/404.html'
});
});
In HomeController.js
siteApp.controller('HomeController', function(){
var vm = this;
vm.error = false;
vm.message = "Halu home page";
});
In ErrorController.js
siteApp.controller('ErrorController', function(){
var vm = this;
vm.error = true;
vm.message = "Error 404";
});
My navigator hides in both of pages although vm.message show true. Why ?
You can help me at : https://github.com/ryantranvn/mean
As this SO answer discusses regarding using this in place of $scope:
When using this style, directives should use the controllerAs property in their return object per the Directive documentation.
A quick workaround for you would be to preface variable names with $scope if you want them to be available in the view:
siteApp.controller('HomeController', function(){
$scope.error = false;
$scope.message = "Halu home page";
});
<div class="container" ng-show="error" nav>{{message}}</div>
As to why the text was being hidden in both your test cases, the variable being used in ng-show was not defined.
Since you are using "this" in the controller function, you will have to declare your Controller with "as" syntax.
If you are using routes to bind the controller, add below code in routes
controller: "HomeController",
controllerAs: "HomeCtrl"
Or if you are directly writing ng-controller in html, use below code
<div ng-controller="HomeCtrl as HomeController">
<div class="container" ng-show="HomeCtrl.error" nav></div>
</div>
Related
Hy,
I want to share data between 1 component (NavBar) and other 1 ctrl (Ctrl1) in ui-view with factory, but it's not work.
When i modify factory in component or ctrl, it modify only his own scope. I want to share factory between ctrl and component.
HTML :
<div ng-app="myApp">
<global-component></global-component>
</div>
Javascript :
var myApp = angular.module('myApp', [ 'ui.router']);
myApp.config(function ($stateProvider, $urlRouterProvider){
$stateProvider.state("state1", {
url: "#",
template: "<p>State 1 </p> <input type=\"text\" ng-model=\"vm.b\"/> {{vm.b}}",
controller: "Ctrl1",
controllerAs: 'vm'
});
$urlRouterProvider.otherwise(function($injector, $location) {
$injector.get('$state').go("state1");
});
});
//Global Component
myApp.component('globalComponent', {
template: 'Global controler </br> <nav-bar></nav-bar> <div ui-view></div>',
controller: "GlobalCtrl",
controllerAs: 'vm'
});
myApp.controller('GlobalCtrl',function(Data){
Data.test="test1";
});
//NavBar
myApp.component('navBar', {
template: 'NavBar <input type=\"text\" ng-model=\"vm.a\"/> {{vm.a}}',
controller: "NavBarCtrl",
controllerAs: 'vm'
});
myApp.controller('NavBarCtrl',function(Data){
var vm=this;
vm.a=Data.test;
});
myApp.controller('Ctrl1',function(Data){
var vm=this;
Data.test="titi";
vm.b=Data.test;
});
myApp.factory('Data', function(){
var data={};
data.test="";
return data;
});
The code :
https://codepen.io/anon/pen/YrdvbV?editors=1111
Thanks
Check out working solution here.
The reason why it's wasn't working in the first palce is that you have changed the reference to data in your setData method. When the reference is changed, your are not working with the same object as before so this vm.a=Data.getData(); is not bound to the same object as on initialization.
In your case, one way to resolve this is to wrap an object around your data (in the example provided, I used data.item instead of just data). Other options are to use $watch or something similar so values could be rebound to ng-model.
I am trying to build a link using routeParams of the route angularJs class. which works pretty well but for some reason it doesn't interpolate my strings.
I have tried the following:
{{username}} as in the controller i set $scope.username = $routeParams.username;
{{ Repo.username }} as the controller is called RepoController.
however both had no result except printing it as a string literal on the screen.my code is as below
App.js
(function() {
var app = angular.module("githubViewer", ["ngRoute"])
app.config(function($routeProvider) {
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.when("/user/:username", {
templateUrl: "user.html",
controller: "UserController"
})
.when("/repo/:username/:reponame", {
templateUrl: "repo.html",
controller: "RepoController"
})
.otherwise({
redirectTo: "/main"
})
});
}());
RepoController.js
(function() {
var app = angular.module("githubViewer")
var RepoController = function($scope, github, $routeParams) {
$scope.username = $routeParams.username;
$scope.reponame = $routeParams.reponame;
app.controller("RepoController", ["$scope", "github", "$routeParams", RepoController]);
}());
Repo.html
<section>
{{ username }}
<br />
{{ repo.name }}
</section>
There is a plunker available:
https://plnkr.co/edit/oGJJOUfCqW8G7OAXxXGa?p=preview
thanks a lot for any help. Cheers!
There are a couple of syntactic and semantic issues in the Plunkr that may be affecting your actual code.
You have a syntax error in the RepoController.js -- you do not close the RepoController function declaration with }
You are not including <script src=RepoController.js> in index.html
$scope.repo is not an object with a name property. In your template, use reponame instead or you could do $scope.repo = {name: $routeParams.reponame}
Ill try and do my best to explain...
It doesn't seem like my controller is connecting/working properly. I'm not sure exactly why, every time I check my syntax seems correct. Here is my route declaration:
angular.module('portfolio', ['ngRoute']).config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/', {
templateUrl: '/public/app/views/main.html',
controller: 'MainCtrl',
controllerAs: 'main'
}).when('/about', {
templateUrl: '/public/app/views/about.html',
controller: 'AboutCtrl',
controllerAs: 'about'
}).when('/Resume', {
templateUrl: '/public/app/views/resume.html',
controller: 'ResumeCtrl',
controllerAs: 'Resume'
}).when('/Samples', {
templateUrl: '/public/app/views/samples.html',
controller: 'SamplesCtrl',
controllerAs: 'Samples'
}).otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(false).hashPrefix('');
});
Just as an example here is my resume view:
<paper-button ng-click="changeEx()" raised>Experience</paper-button>
<paper-button ng-click="changeSkills()" raised>Skills</paper-button>
<paper-button ng-click="changeEdu()" raised>Education</paper-button>
<paper-button ng-click="changeMisc()" raised>Misc.</paper-button>
<div ng-hide="exp">
<p>Experience</p>
</div>
<div ng-show="skills">
<p>Skills</p>
</div>
<div ng-show="education">
<p>Education</p>
</div>
<div ng-show="misc">
<p>Misc.</p>
</div>
Finally, here is the declaration of the controller for the resume view:
angular.module('portfolio', []).controller('ResumeCtrl', function () {
this.exp = true;
});
Obviously, this controller is incomplete but I am simply trying to test it by using this variable.
Do not use square brackets when you are referencing a module that has already been declared. This is interpreted by Angular as declaring a new module:
angular.module('portfolio').controller('ResumeCtrl', function () {
this.exp = true;
});
The next thing I would check is your main HTML page. Do you have this directive somewhere on your page:
<div ng-view></div>
Another problem is that you are declaring controllerAs in your route as Resume, but you are using this.exp to assign your variable and also trying to reference exp in your view. You need to follow this pattern instead, or use $scope:
angular.module('portfolio').controller('ResumeCtrl', function () {
var Resume = this;
Resume.exp = true;
});
And in your view you should reference the variable using the same name you defined in controllerAs:
<div ng-hide="Resume.exp">
<p>Experience</p>
</div>
Or, alternatively, you can keep your view the same, but assign your variable using $scope:
angular.module('portfolio').controller('ResumeCtrl', function ($scope) {
$scope.exp = true;
});
I am trying to bring to my homepage a custom directive which will print me some output.
In the network tab in my devtools I just saw that my controller loads twice.
controller:
var homeController = function($log,leaguesFactory){
var self = this;
self.leagues = [];
leaguesFactory.loadLeagues()
.then(function(leagues){
self.leagues = leagues.data.Competition;
});
self.message= 'test message';
};
directive:
var leaguesTabs = function(){
return {
restrict : 'E',
templateUrl : 'app/home/leagues-tabs.tpl.php',
scope: {
leagues: '='
},
controller: 'homeController',
controllerAs: 'homeCtrl'
};
};
ui-router states:
$stateProvider
.state('home',{
url : '/',
templateUrl : 'app/home/home.tpl.php',
controller : 'homeController',
controllerAs: 'homeCtrl'
})...
I just want to use my homeCtrl in the directive, but it seems that the state provider loads it also and make it load twice. If I remove the controller from the directive then I don't get access to the homeCtrl, if I remove the homeCtrl from the stateprovider than I don't have access in the home.tpl.php
home.tpl.php:
<div>
<leagues-tabs></leagues-tabs>
</div>
any idea?
Actually problem related to next steps:
ui-router start handling url '/'
ui-router create an instance of 'homeController'
ui-router render the view 'app/home/home.tpl.php'
Angular see usage a custom directive - 'leagues-tabs'
'leagues-tabs' directive create an instance of 'homeController'
'leagues-tabs' render the view 'app/home/home.tpl.php'
You can follow any of next possible solutions:
Change controller for 'leagues-tabs' to something special
Remove controller usage from ui-router state definition
You can try this one http://plnkr.co/edit/LG7Wn5OGFrAzIssBFnEE?p=preview
App
var app = angular.module('app', ['ui.router', 'leagueTabs']);
UI Router
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/leagues');
$stateProvider
.state('leagues', {
url: '/leagues',
templateUrl: 'partial-leagues.html',
controller: 'LeaguesController',
controllerAs: 'ctrl'
});
}]);
Controller
app.controller('LeaguesController', ['$http', function($http) {
var self = this;
$http.get('leagues.json').success(function(data){
self.leagues = data;
})
}]);
View
<div>
<league-tabs leagues="ctrl.leagues"></league-tabs>
</div>
Directive
var leagueTabs = angular.module('leagueTabs', []);
leagueTabs.directive('leagueTabs', function(){
return {
restrict : 'E',
templateUrl : 'partial-league-tabs.html',
scope: {
leagues: '='
},
controller: 'LeagueTabsController',
controllerAs: 'leagueTabs'
}
});
leagueTabs.controller('LeagueTabsController', function($scope){
var self = this
$scope.$watch('leagues', function(leagues){
self.leagues = leagues;
})
})
Directive View
<div>
<ul ng-repeat="league in leagueTabs.leagues">
<li>{{league.name}}</li>
</ul>
</div>
I just started with angularJS and I have a question:
How can I access a variable defined with $rootScope in a templateUrl function?
Here is my code:
myApp.config(['$routeProvider',
function($routeProvider, $rootScope) {
$routeProvider.
when( '/', {
templateUrl: 'partials/login.html',
controller: 'loginCtrl'
}).
when( '/home', {
templateUrl: function($rootScope){
console.log($rootScope.utilisateur.user.role_id);
if ($rootScope.utilisateur.user.role_id==2){
return 'partials/home.html';
}
else return 'partials/login.html';
},
controller: 'homeCtrl'
}).
otherwise({redirectTo:'/'});
}]);
It tells me that utilisateur is undefined.
I defined it in the index controller:
$rootScope.utilisateur = null;
$rootScope.rapports = null;
And then in the LoginCtrl:
var user = Authentification.login(email,password);
user.success(function(response){
$rootScope.utilisateur = response;
console.log($rootScope.utilisateur);
$location.path('/home');
});
You cannot use the $rootScope inside of the config block, as the config block runs before the $rootScope is created. Constants and providers may be used inside of the config block instead. If constants are not an option for you, you may want to redirect to the correct url inside of your homeCtrl.
[EDIT] Added possible solution from comment below:
Option 1: Have 2 different routes
/admin/home
/home
Option 2: Switch templates according to permission inside of controller/view
home.html
<div ng-switch="utilisateur.user.role_id">
<div ng-switch-when="2">
<!-- is admin -->
</div>
<div ng-switch-default>
<!-- not admin -->
</div>
</div>
Not the ideal solution, but it'd work for what you are trying to do, based on your comments below
Your problem seems like you have two different views, and on condition base you have to redirect views.
Pass the parameters in url like from your views (Create/Edit link etc.) As i have set the cookie on login and accessed here as a parameters or you can use different way to access the parameters.
''
And your config in $routeProvider use like this:
$routeProvider.when("/editTest/:ID/:flagTab",
{
templateUrl: function (params) {
var flag = params.flagTab;
if (flag == 'tabPanelView') {
return '/apps/templates/editTest.html';
}
else {
return '/apps/templates/editTestPageView.html';
}
},
controller: 'EditTestController'
});.
Refere a link swtiching views in routeProvider based on condition
Instead of describing different ways to achieve what you would like to, the code snippet below answers the actual question that was asked:
How can I access a variable defined with $rootScope in a templateUrl function?
The answers above and here imply there is no way to reference $rootScope within the config/$routeProvider. While that may strictly be true, there is a simple way to access the $rootScope through $routeProvider. Below is how to do this:
Sample HTML:
<div ng-app="myApp">
<div ng-controller="masterController">
<script type="text/ng-template" id="home.html">{{something}}</script>
Page
<div ng-view></div>
</div>
</div>
Sample javascript:
var myApp = angular.module('myApp',[],function($routeProvider) {
$routeProvider
.when('/home',{templateUrl:'home.html'})
.when('/page',
{
template:'<p>{{something}}</p>',
controller:'masterCtrlWrapper'
})
.otherwise({redirectTo:'/home'});
});
myApp.controller('masterCtrlWrapper', function($rootScope)
{ $rootScope.changeVariable(); });
myApp.controller('masterController', function($rootScope)
{
$rootScope.something = 'This is the $rootScope talking.'
$rootScope.pressCount = 0;
$rootScope.changeVariable = function()
{ $rootScope.something = "This function was run " + $rootScope.pressCount++ + " times."; };
});
Like others have said, $rootScope doesn't exist yet, but unlike their answers, it doesn't at all mean you can't use it at all, you just have to code-in the wait.
Here is your example working but just printing since we dont have the templates.
myApp
.provide('home', function() {
var $rootScope = null;
this.templateUrl = function() {
var check =
$rootScope.utilisateur &&
$rootScope.utilisateur.user.role_id
;
console.log(check);
return (check) ? 'partials/home.html' : 'partials/login.html';
};
this.controller = 'homeCtrl';
this.resolve = {load:['$rootScope', function(fetched) { $rootScope = fetched; }]};
this.$get = function() { };
})
.config(['$routeProvider', 'homeProvider', function($routeProvider, homeProvider) {
$routeProvider
.when('/', {
templateUrl : 'partials/login.html',
controller : 'loginCtrl'
})
.when('/home', homeProvider)
.otherwise({redirectTo:'/'})
;
}])
;