This question already has answers here:
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
(3 answers)
Closed 2 years ago.
I have my front part of the application in AngularJs with JSP files.
The index.jsp use the directive ng-view to show the views :
index.jsp
<div ng-view autoscroll="true" style="overflow: auto;"></div>
and the app.js to link with $routeProvider the controller to the view (home.jsp do some includes of views.jsp) :
app.js
$routeProvider
.when('/Error', {
controller: 'LoginController',
templateUrl: 'modules/authentication/views/errorConnexion.jsp',
hideMenus: true
})
.when('/', {
controller: 'HomeController',
templateUrl: 'modules/home/views/home.jsp'
})
.otherwise({ redirectTo: '/login' });
and my HomeController uses fields to hide or show some DOM elements :
HomeController.js
app.controller('HomeController',
['$timeout',
'service',
'$scope',
'$rootScope',
'$filter',
'$location',
'$window',
'ModalService',
'ngTableParams',
'$http',
'$interval',
'Excel',
function($timeout, service, $scope,
$rootScope, $filter, $location, $window,
ModalService, ngTableParams, $http, $interval, Excel) {
$scope.Hide_Module = true;
})]);
My controller child :
ChildController.js
app
.controller('ChildController',
function() {
$scope.field = "random";
}
);
And finally the problem, the view :
view.jsp
<section ng-controller="ChildController" class="content"
ng-hide="Hide_Module">
The problem is : If I remove ng-controller directive on the section tag, all is alright.
But if I add it, the main view (index.jsp) shows view.jsp......
So I want to know what I did wrong and moreover how angularjs deals with controllers inheritance and how they are binded through the views ?
Find out by myself, here two errors in my project :
Link to the controller file missing
<script src="modules/controllers/sub/childController.js"></script>
(Added in the index.jsp)
Data shared through $scope variable only in Object syntax
Define $scope.myObject = { key: value, ... } in the parent controller instead of primitives and arrays.
Add the $scope argument in the child controller as :
app.controller('ChildController', ['$scope', function($scope) { } ]);
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 keep seeing examples on this but I don't know what I am doing wrong.
I load an item and its content into ng-view. When I refresh the page, it disappears. I have passed a parameter to the URL of the state and I am lost what to do next.
People have talked about $stateParams which I can log from my controller and I can see that item with id: 3 has been selected.
How do I keep the view populated with this item even on refresh? An example with my code would be greatly appreciated.
var app = angular.module('myApp', ['ngRoute', 'ui.router']);
app.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', '$routeProvider', function($stateProvider, $locationProvider, $urlRouterProvider, $routeProvider) {
$urlRouterProvider
.otherwise('/patents');
$stateProvider
.state("patents", {
url: "/patents",
templateUrl: "templates/patents/list/list-patents.htm",
controller: "patentListCtrl",
})
.state("patents.item", {
url: "/:id",
templateUrl: function() {
//THIS IS WHERE I AM NOT SURE HOW TO PASS THE URL THE ID
},
controller: "patentItemCtrl"
})
}]);
app.controller('patentItemCtrl', ['$scope', 'patentTabService','$stateParams', '$state', '$routeParams', function($scope, patentTabFactory, $stateParams, $routeParams){
console.log($stateParams.id)
}])
You should be able to to retrieve the required data by making a call your data service and then assign to your view. In your case call patentTabService to get patent with the id and then load that patent object into your view. For example, note I am assuming you already have some way to get a patent by id in your service:
app.controller('patentItemCtrl', ['$scope', 'patentTabService','$stateParams', '$state', '$routeParams', function($scope, patentTabFactory, $stateParams, $routeParams){
$scope.patent = {};
if (Number.isInteger($stateParams.id) ){
$scope.patent = patentTabFactory.getPatent($stateParams.id);
}
console.log($stateParams.id)
}])
I'm trying to understand the routing before I start building my app but it doesn't seem to work.
I have a basic app for tests in which I created 3 html files matching 3 different views and I wish to change the displayed view depending on the routes.
But I always see the index view.
Here are the files :
app.js :
'use strict';
angular.module('BalrogApp', ['ngRoute', 'ui.bootstrap', 'BalrogApp.controllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '../index.html'
})
.when('/requests', {
templateUrl: '../views/requestsList.html'
})
.when('/projects', {
templateUrl: '../views/projectsList.html'
})
.otherwise({
redirectTo: '/lol'
});
}]);
requestsController.js :
'use strict';
var requestsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
requestsControllerModule.controller('requestsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Request";
this.studentMark = 75;
});
projectsController.js :
'use strict';
var projectsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
projectsControllerModule.controller('projectsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Project";
this.studentMark = 75;
});
The html files are almost the same except for some words and for the controller associated to each of them.
Here are the few lines that change between html wiews :
index.html :
index view
<div class="row-fluid" ng-controller="requestsController as rc">
<div class="span2">{{rc.studentName}} </div>
</div>
requestsList.html :
Request view
<div class="row-fluid" ng-controller="requestsController as r">
<div class="span2">{{r.studentName}} </div>
</div>
projectsList.html
Project view
<div class="row-fluid" ng-controller="projectsController as p">
<div class="span2">{{p.studentName}} </div>
</div>
Byt no matter what the route is, if I added '/projects' or '/requests' to the url, I stay on the index view.
Any idea what I am doing wrong ?
Make sure you have ng-view attribute or element set in your index.html. If it is absent the router won't work.
Another good practice would be to set your view controller on the router, like so:
$routeProvider
.when('<route_name>', {
templateUrl: '../<tempate>.html',
controller: '<controller_name>',
controllerAs: 'myController'
})
1. On your base file (usually index.html), make sure you have an ng-view directive that will be used to load all the partial views
2. Are all your html templates in the same location as the base file? If yes, the instead of having the templateUrl as "../index.html" you could try setting it to "/index.html" instead. The first checks for the html file outside of the directory where the base file is located, while the second checks for it in the same directory
I am new with anglarjs and I am working on ng-view example which is available here, actually the problem is that when I run application in firefox it show me only text in index.page, not shown any result related to angularjs.
index.html
<div ng-controller="MainCtrl as main">
Choose:
Moby |
Moby: ch1 |
Gatsby |
Gatsby: ch4 |
Scarlet Letter<br/>
</div>
<pre>$location.path() = {{main.$location.path()}}</pre>
<pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
<pre>$route.current.params = {{main.$route.current.params}}</pre>
<pre>$routeParams = {{main.$routeParams}}</pre>
app.js
The controller is define here.
var myApp = angular.module('ngviewExample',['ngRoute'])
.config(['$routeProvider','$locationProvider',
function ($routeProvider,$locationProvider){
$routeProvider
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookCtrl',
controllerAs: 'book'
});
$locationProvider.html5Mode({
enabled : true,
requireBase : false
});
}])
.controller('MainCtrl', ['$route', '$routeParams', '$location',
function($route, $routeParams, $location) {
this.$route = $route;
this.$location = $location;
this.$routeParams = $routeParams;
}])
.controller('BookCtrl', ['$routeParams', function($routeParams) {
this.name = "BookCtrl";
this.params = $routeParams;
}]);
All the angularjs files are loading fine but it's not showing any error in Firebug console. But when I debug this code I don't know why it go inside the following code on accessing the url http://localhost:8383/TestingDirective/index.html
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookCtrl',
controllerAs: 'book'
});
Also shown in the snap-shot.
Can anyone please tell me what I am missing here, only text of index.html page show on the page and nothing else.
Any help would be appreciated.
So I am trying to render a subview within a template but I want to define the state inside of the subviews controller on click of an element. The reason for splitting it out from the main controller is that I will be having subviews within the initial subview.
However, I get the following error:
Error: [$injector:modulerr] Failed to instantiate module
ivy.quote.controllers.durationCtrl due to: TypeError: Cannot read
property 'navigable' of undefined
This happens before I have even clicked the button which basically does the following
$state.transitionTo('quote.duration');
quote.tpl.html
<div class="quote grid" disable-scroll>
<div modal-from-bottom modal-hidden="calendarHide"
modal-content-class="quote__keypad" modal-speed="200" ui-view></div>
</div>
quoteCtrl.js
angular.module('ivy.quote.controllers.quoteCtrl', [
'ivy.quote.controllers.keypadCtrl',
'ivy.quote.controllers.durationCtrl',
'ivy.quote.services.quoteManager',
'ui.router',
'ivy.quote.calendar',
'wn.keypad',
'wn.gesture.disableScroll'
])
/**
* Configure UI Router
*/
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('quote', {
url: '/quote',
controller: 'quoteCtrl',
templateUrl: 'quote/templates/quote.tpl.html'
});
}])
.controller('quoteCtrl', ['$scope', '$timeout', '$state', 'quoteManager',
function ($scope, $timeout, $state, quoteManager) {
}]);
duration.tpl.html
<div class="quote__calendar">
<h2>DURATION</h2>
<div ui-view></div>
</div>
durationCtrl.js
angular.module('ivy.quote.controllers.durationCtrl', [
'ui.router'
])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('quote.duration', {
url: '/duration',
controler: 'durationCtrl',
templateUrl: 'quote/templates/duration.tpl.html'
});
}])
.controller('durationCtrl', ['$scope', function ($scope) {
console.log('durationCtrl', $scope);
}]);
Your controller should be spelled "controller", not "controler", but otherwise, this looks like all the tutorials I've seen on subviews.