I have the following div in my index.html, whose controller is MainCtrl. This is the div used to load views from different controllers.
<div ng-controller="MainCtrl">
<div ng-view></div>
</div>
And these are my controllers:
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/main', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
}).
when('/about', {
templateUrl: 'views/about.html',
controller: 'MainCtrl'
}).
when('/services', {
templateUrl: 'views/services.html',
controller: 'ServicesCtrl'
}).
when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
}).
otherwise({redirectTo: '/main'})
}])
.controller('MainCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('data/services.json').then(function(response){
$scope.services = response.data;
});
}])
.controller('ServicesCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('data/services.json').then(function(response){
$scope.services = response.data;
});
}])
.controller('ContactCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('data/locations.json').then(function(response){
$scope.locations = response.data;
});
}]);
It all works fine, but I do not understand how do all the views from different controllers get loaded automatically inside the <div ng-controller="MainCtrl"> ?
So for example if I go to mysite/services, it loads services.html, even though its controller is ServicesCtrl.
It seems logical to me that it should only load the view from MainCtrl, which is main.html and about.html, yet it loads them all irrespective of controller names, how come?
There shouldn't be an ng-controller="MainCtrl" because the controllers for each route are defined in your routing configuration.
If you have this in your page then when about or main load you will actually initialize 2 instances of MainCtrl. One instance will be invoked by the router and the other by ng-controller and this can be problematic.
That being said you could have an outer controller but it wouldn't be the same as the ones used in the routes
Related
I am trying to figure out how to build a SPA with angularjs. My routes are working and each partial page is loading in ng-view properly. I'm trying to load external json data. I had it working onnce but I can't figure out what I'm doing wrong. The goal is to list products and have a details page for each product. Any help would be greatly appreciated. Here's my code:
app.js
var myApp = angular.module('app', ['ngRoute']);
myApp.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
$routeProvider.
when('/home',{
templateUrl: 'partials/home.html',
controller: "storeCtrl"
}).
when('/about',{
templateUrl: 'partials/about.html',
controller: "storeCtrl"
}).
when('/computers',{
templateUrl: 'partials/computers.html',
controller: "storeCtrl"
}).
when('/smartphones',{
templateUrl: 'partials/smartphones.html',
controller: "storeCtrl"
}).
when('/tablets',{
templateUrl: 'partials/tablets.html',
controller: "storeCtrl"
}).
otherwise({
redirectTo: '/home'
});
}]);
myApp.controller('storeCtrl', ['$scope', '$http', function($scope, $http) {
$scope.homeHeading = 'Home';
$scope.aboutHeading = 'About Us';
$scope.computersHeading = 'Computers';
$scope.smartphonesHeading = 'Smartphones';
$scope.tabletsHeading = 'Tablets';
$http.get('products.json').success(function(data) {
$scope.products = data;
});
console.log($scope.products);
}]);
computers.html
<div ng-controller="storeCtrl">
<h1>{{computersHeading}}</h1>
<div ng-repeat="item in products">
<p>{{ item.name }}</p>
</div>
</div>
You should try this
$http.get('products.json').then(function(result) {
$scope.products = result.data;
});
And remove ng-controller from the view as you have already defined it in myApp.config()
Try to use $http.get service which returns a promise object.
There are 2 views with respective controllers.
The links are in View1.Clicking on this link should load View2 and also read the parameters.
This is what I have tried but the alert says - undefined.
View2 can load with/without params - each case having a different workflow.
View1.html:
<div ng-controller="view1ctrl">
<a href="#/view2/pqid/775/cid/4" >Link1</a>
</div>
app.js:
var app = angular.module('app', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/view1', {
templateUrl: 'App/views/view1.html',
controller: 'view1ctrl'
})
.when('/view2', {
templateUrl: 'App/views/view2.html',
controller: 'view2ctrl'
})
.when('/view2/:pqid/:cid', {
templateUrl: 'App/views/view2.html',
controller: 'view2ctrl'
})
.otherwise({
redirectTo: '/view1'
});
}]);
view2ctrl.js:
app.controller("view2ctrl", ['$scope','$routeParams',function ($scope, $routeParams) {
var init = function () {
alert($routeParams.pqid);
}
init();
}]);
You are nearly there:
.when('/view2/:pqid/:cid'
maps to a URL in this format :
view2/1234/4567
1234 being the pqid and 4567 the cid.
So your routing, I think is working, just change the link to #/view2/775/4.
Or if you want to keep the same link change your routing to:
#/view2/pqid/:pqid/cid/:cid
I've been struggling with using ng-view for my subview of my application. I've followed multiple tutorials and have even checked the routeProvider and locationProvider attributes to ensure that they were pointing to the correct path.
index.html
<html ng-app="elephantApp">
...
<div id="view" ng-view>{{$scope.message}}</div>
...
</html>
application.js
/*
Main AngularJS for Elephant Blog App
*/
var elephantApp = angular.module("elephantApp", ["ngRoute", "ui.bootstrap"]);
elephantApp.config(function ($routeProvider, $locationProvider){
$routeProvider
// Home
.when('/', {
templateUrl: "app/partials/home.html",
controller: "ElephantController"
})
.when('/about', {
templateUrl: 'partials/about.html',
controller: 'PageCtrl'
}) ;
$locationProvider
.html5Mode(true);
});
elephantApp.controller("ElephantController", function($scope, $route, $routeParams, $location){
$scope.contentClass = 'content-home';
$scope.message = {message: "Hi"};
});
elephantApp.controller("PageCtrl", function($scope, $route, $routeParams, $location){
$scope.contentClass = 'content';
$scope.model = {message: "Hey!"};
});
/*
function ElephantController($scope, $route, $routeParams, $location){
$scope.contentClass = 'content-home';
$scope.$route = $route;
$scope.$location = $location;
$scope.$routeParams = $routeParams;
$scope.model = {message: "Hey"};
}
*/
So I have no idea what's going on at all.
I have even tried to do code like:
// Pages
.when("/about", {templateUrl: "partials/about.html", controller: "PageCtrl"})
.when("/faq", {templateUrl: "partials/faq.html", controller: "PageCtrl"})
.when("/contact", {templateUrl: "partials/contact.html", controller: "PageCtrl"})
// Blog
.when("/blog", {templateUrl: "partials/blog.html", controller: "BlogCtrl"})
.when("/blog/post", {templateUrl: "partials/blog_item.html", controller: "BlogCtrl"})
// else 404
.otherwise("/404", {
templateUrl: "partials/404.html",
controller: "PageCtrl"
});
I would like to use the above code as it is what I mainly want to do. Though it isn't working. The ng-includes work but not my ng-views. Am I missing something?
Thanks.
By default, a route in angular is the hash in the URI path after #, for example http://app/#/about. By setting $locationProvider.html5Mode to true how you done, we can write without # http://app/about, but need that server always returning index.html. For this purposes you can use, for example, Express server: http://www.seankenny.me/blog/2013/08/05/angularjs-in-html5-mode-with-expressjs/
I have a tab I want to be activated by a link like this:
http://localhost:8020/client#/content
Therefore I have this list-element:
li ng-show="showContentItemsTab" ng-class="{active: isActive('/content')}">Content</li>
But I also want it to be active when sublinks are called:
http://localhost:8020/client#/content/531443caeb3f95600ef92e3f
Is there a way to apply all sublinks after /content ?
Something like:
li ng-show="showContentItemsTab" ng-class="{active: isActive('/content/*')}">Content</li>
Following the official angular js tutorial, you can set up routing as follows.
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'
});
}]);
The controller will be
var phonecatControllers = angular.module('phonecatControllers',[]);
phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$http.get('phones/' + $routeParams.phoneId + '.json').success(function(data) {
$scope.phone = data;
});
}]);
So your can be fetched by using $routeParams
I've tried multiple solutions found on SO but I'm obviously missing something fundamental as no matter what I try I cannot get the particle view to change on submission of a form (or click of a button).
Here's the code:
propertyControllers.controller('HomeCtrl', ['$scope', 'SearchData', '$location',
function($scope, SearchData, $routeParams, $location) {
SearchData.set('postcode', $scope.postcode);
SearchData.set('radius', $scope.radius);
SearchData.set('minBeds', $scope.minBeds);
SearchData.set('minPrice', $scope.minPrice);
$scope.submit = function() {
$location.path('/properties');
}
}]);
And in the home.html partial
<input type="submit" class="topcoat-button--cta" value="Search">
My routing config
var propertyApp = angular.module('propertyApp', [
'ngResource',
'ngRoute',
'propertyControllers'
]);
propertyApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
}).
when('/properties', {
templateUrl: 'partials/property-list.html',
controller: 'PropertyListCtrl'
}).
when('/properties/:propertyId', {
templateUrl: 'partials/property-detail.html',
controller: 'PropertyDetailCtrl'
}).
otherwise({
redirectTo: 'home'
});
}]);
Could someone point me in the right direction? The docs seem overly complex and all the simple examples I've found do what I'm doing...
The parameters in string form and the actual parameters don't match:
controller('HomeCtrl', ['$scope', 'SearchData', '$location',
function($scope, SearchData, $routeParams, $location)
You forgot to add '$routeParams' in the array, before '$location'.