I want to change an image after going to /tab1. This can be done by 'ng-click'. But need to be done using AngularJS routing.
Html file:
<div class = "body" ng-controller = "app">
<div class = "column1">
<div class = "tab1">
<img ng-src="{{ imageUrl }}">
</div>
Controller.js :
var application = angular.module('mainApp', ['ngRoute']);
application.controller('app', function($scope) {
console.log("Executed");
$scope.imageUrl = 'profile-icon.png';
});
application.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/tab1', {templateUrl: 'tab1.html', controller: HomeCtrl}).
when('/tab2', {templateUrl: 'tab2.html'}).
when('/tab3', {templateUrl: 'tab3.html'}).
otherwise({redirectTo: '/'});
}]);
function HomeCtrl($scope) {
console.log("Inside ToggleImage");
$scope.imageUrl = 'profile-icon-clicked.png';
}
Page successfully loading the 'profile-icon.png'. But after clicking image is not changing. But I can see the output 'Inside ToggleImage' in browser console.
What's wrong here?
And imageUrl are in different scope in two controllers. If you want them to be same every where use $rootscope not $scope
That's because you modify property of child scope, not parent scope. See https://github.com/angular/angular.js/wiki/Understanding-Scopes for explanations on scope inheritance.
The easiest way to solve this is to have an object on a parent scope.
var application = angular.module('mainApp', ['ngRoute']);
application.controller('app', function($scope) {
console.log("Executed");
$scope.settings= {imageUrl: 'profile-icon.png'};
});
application.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/tab1', {templateUrl: 'tab1.html', controller: HomeCtrl}).
when('/tab2', {templateUrl: 'tab2.html'}).
when('/tab3', {templateUrl: 'tab3.html'}).
otherwise({redirectTo: '/'});
}]);
function HomeCtrl($scope) {
console.log("Inside ToggleImage");
$scope.settings.imageUrl = 'profile-icon-clicked.png';
}
Related
I'm trying to setup one of my first angular projects and am having trouble getting to grips with the routing.
On page load I see the initial template that has been set by the preferencesDirective, which is great.
When I click the "Change Template" button I want it to change to another template but nothing happens. If I set the template url's in the $routeProvider to something invalid then I see a 404 error in the debugger which tells me something must be working but nothing happens when the template url is valid.. How do I get it to change correctly?
Thanks.
<div id="PreferencesApp" class="" ng-app="clientPreferencesModule">
<preferences-directive factory-settings="clientPreferences"></preferences-directive>
Change Template
</div>
<script>
var app = angular.module("clientPreferencesModule", ["ngResource", "ngRoute"]);
//var app = angular.module("clientPreferencesModule", ["ngRoute"]);
app.config(function ($routeProvider) {
$routeProvider.when("/", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences/:id", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Details", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/DetailsTemplate.html' });
});
app.controller('clientPreferencesController', clientPreferencesController);
clientPreferencesController.$inject = ["$scope", "$resource", "$rootScope", "$http", "$route", "$location"];
function clientPreferencesController($scope, $resource, $rootScope, $http, $route, $location) {
this.model = #Html.Raw(JsonConvert.SerializeObject(Model));
$scope.location = $location.path();
}
app.directive('preferencesDirective', preferencesDirective);
function preferencesDirective() {
return {
restrict: 'EA',
scope:
{
factorySettings: '='
},
controller: 'clientPreferencesController',
controllerAs: 'pc',
bindToController: true,
templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html'
}
}
</script>
For routing to work you've to create different views along with its associated controller & then have directive inside that view. And also you'll need ng-view directive in index.html in which all the routes view going to be loaded. And also preferencesDirective should only contain the reusable unique functionality, & the complete app view, so that you can have it different views with different data sets alongside different view components.
So, your template can be:
<div id="PreferencesApp" class="" ng-app="clientPreferencesModule">
Change Template
<div ng-view></div>
</div>
Now for different routes you can have each different controllers or if you want to handle it in one controller the have only one, but different from directive's controller, so it can be,
app.config(function ($routeProvider) {
$routeProvider.when("/", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences/:id", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Details", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/DetailsTemplate.html' });
});
Have preferencesDirective in all these templates. (This will now potentially change the directive's template but you can have changing dom of each view in views's templates & keep directive's template constant)
Now in viewController by making use of $routeParams you can check the current route & send different data to preferencesDirective's controller.
Now if you must want to change directives template conditionally then make use of ng-include inside directive's template.
function preferencesDirective() {
return {
restrict: 'EA',
scope:
{
factorySettings: '=',
templateSrc: '='
},
controller: 'clientPreferencesController',
controllerAs: 'pc',
bindToController: true,
templateUrl: '<ng-include src="pc.template()"></ng-include>'
}
}
function clientPreferencesController($scope, $resource, $rootScope, $http, $route, $location) {
this.model = #Html.Raw(JsonConvert.SerializeObject(Model));
$scope.location = $location.path();
$scope.template = function(){
if($scope.templateSrc) {
return '/AngularTemplates/ClientPreferences/'+ $scope.templateSrc + '.html';
}
}
}
Here share that templateSrc from viewController based on current route.
I'm trying to use Angular with my Codeigniter project. The problem is that it doesn't load the proper template file through angular router.
In the root instead of showing templateUrl: 'index.php/welcome/home', it loads the index.php/welcome. It loads the index page inside the controller instead of the ones I have specified.
Below is my code:
JS
var app = angular.module('MyCtrl', ['ngRoute', "ui.bootstrap.modal"]);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'index.php/welcome/home',
controller: 'mainController'
})
.when('/user', {
templateUrl: 'index.php/user/account',
controller: 'userController'
})
});
app.controller('mainController', function($scope) {
$scope.message = 'main con';
});
app.controller('userController', function($scope) {
$scope.message = 'user con!';
});
Welcome controller in Codeigniter:
public function home(){
$this->load->view('home');
}
Can someone tell me why this is not working and what I have done wrong?
I have just started learning angularJS but i can notice the same thing so many time that at some places when we start writing a function in angularJS i noticed that some people define the function they are going to use like this
var mainApp = angular.module("mainApp", ['ngRoute']);
mainApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/addStudent', {
templateUrl: 'addStudent.htm',
controller: 'AddStudentController'
}).
when('/viewStudents', {
templateUrl: 'viewStudents.htm',
controller: 'ViewStudentsController'
}).
otherwise({
redirectTo: '/addStudent'
});
}]);
But the same function is working fine if we just write the function without this ['$routeProvider' like this
var mainApp = angular.module("mainApp", ['ngRoute']);
mainApp.config(function($routeProvider) {
$routeProvider.
when('/addStudent', {
templateUrl: 'addStudent.htm',
controller: 'AddStudentController'
}).
when('/viewStudents', {
templateUrl: 'viewStudents.htm',
controller: 'ViewStudentsController'
}).
otherwise({
redirectTo: '/addStudent'
});
});
I know there is no big difference when coming to code writing but still is there any difference in both the ways. If yes, then is it about minifying? and is there any negative point other that that of using it?
Thanks in advance!
mainApp.config(['$routeProvider', function($routeProvider) {
}]);
This type define a controller is callled Inline Array Annotation. And It is min-safe. min-safe mean if you minify your code then it will still work.
mainApp.config(function($routeProvider) {
});
This type of define a controller is called 'Implicit Annotation'. And its not min-safe. min-safe mean if you minify your code then it will not work.
And there a another way to declare a controller $inject Property Annotation
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
read more info click here
I needed a way to access the parent scope of a controller without having to inject $scope to do so. The reason behind this is that I'm building a SPA and I wanted to apply a class to the body element depending on the current page. I don't want to have to inject $scope into every single one of my controllers just for the sole purpose of changing the class. Also please let me know if I'm looking at this the wrong way, if there is a way to encapsulate this functionality using $routeprovider or a service that is fine too. I've just recently begun to use Angular so I apologize in advance if the solution is really simple, but I was not able to find anything similar to my situation by googling.
Here is the basic setup:
index.html
<body ng-controller="BodyController as body" class="contact-page">
<nav> ... </nav>
<main ng-view>
<div ng-controller="ContactController as contact>
Contact Page loaded in on click
</div>
</main>
</body>
body.controller.js
(function() {
angular
.module('app')
.controller('BodyController', BodyController);
function BodyController() {
var body = this;
}
})();
contact.controller.js
(function() {
angular
.module('app')
.controller('ContactController', ContactController);
ContactController.$inject = [];
function ContactController($scope) {
var vm = this;
}
})();
app.routes.js
(function () {
angular
.module('app')
.config(routes);
routes.$inject = ['$routeProvider', '$locationProvider'];
function routes($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/home/home.html',
controller: 'HomeController',
controllerAs: 'home'
}).when('/contact', {
templateUrl: 'app/contact/contact.html',
controller: 'ContactController',
controllerAs: 'contact'
}).otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}
})();
Wondering if there's an 'angular specific' way to try and achieve this.
I have a page with some views. When a user clicks an anchor, the views change, simple enough. What I'm curious is, if when the user clicks, is it possible to store a variable (say the span) then pass it to the $routeProvider to load the content a bit more dynamically?
so for anchor tag #name1, when that view is displayed, I can pass "name1" into nameHolder as a variable to load some files with same name.
HTML
<span>name1</span>
JS
var nameHolder = [];
var sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/' + nameHolder, {
templateUrl: 'templates/individkcd.html',
controller: 'individ',
nameofuser: nameHolder
}).
when('/', {
templateUrl: 'templates/home.html'
});
}]);
sampleApp.controller('individ', function($scope, $route) {
$scope.img = $route.current.nameHolder;
});
Thanks for any info.
UPDATED:
Solution at new thread.
angular js - passing a variable into $routeProvider
You need to add the parameter to your $routeProvider template:
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/' + nameHolder, {
templateUrl: 'templates/individkcd/:nameHolder',
controller: 'individ'
}).
when('/', {
templateUrl: 'templates/home.html'
});
}]);
Then in your target controller use $routeParams:
sampleApp.controller('individ', function($scope, $routeParams) {
$scope.img = $routeParams.nameHolder;
});
From the $routeProvider docs linked above:
path can contain named groups starting with a colon: e.g. :name. All
characters up to the next slash are matched and stored in $routeParams
under the given name when the route matches