I am trying to learn AngularJS and I came across a problem where I have difficulties to solve it.
I have small application based on this template.
<!doctype html>
<html lang="en" ng-app="fff">
<head>
<meta charset="utf-8" />
<head>
<body class="{{bodyClass}}">
<div ng-view></div>
<script src="/static/js/all.js"></script>
</body>
</html>
I would like to change bodyClass in ng-view. What is the best practice solution such a case?
The variable used in your body must come from some controller. Inside ng-view you will most likely also have a page with a controller. This controller is now a child of the 'body' controller. This means that you can access parent variables from your 'child' controller.
Please read this: Scopes. The is a very, very good read about scopes. I even think this is a must read.
You could try this using route change by putting controller there
app.run(function($rootScope) {
$rootScope.$on('$routeChangeSuccess', function(ev,data) {
if (data.$route && data.$route.controller)
$rootScope.controller = data.$route.controller;
})
});
and change <body class="{{bodyClass}}"> to <body ng-class="controller">
Check http://plnkr.co/edit/fR6gSqeXbROl410tgzPJ?p=preview
The easiest would be to take object and define the bodyClass over it. Something like
$scope.appStyles={bodyClass:'default'}
This property should be defined over a controller defined on parent of ng-view html.
Now you would get this appStyle object in all ng-view scope,as they inherit the parent $scope. Which also means you can change it anywhere like
$scope.appStyles.bodyClass='newClass';
A better approach would be to move these settings into a service and share.
Related
Couldn't get start with angularjs, need help.
My app.js
var app = angular.module('cartApp', ['ui.router']);
app.controller('dashboardCtrl', function() {
var dash = this;
dash.something = "something";
});
index.html
<!DOCTYPE html>
<html lang="en" ng-app="cartApp">
<head>
<meta charset="UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
</head>
<body ng-controller="dashboardCtrl">{{something}}
/body>
</html>
I think I messed up but don't know where is it.
You have all your bindings available inside controller context(this), so you should use controllerAs pattern to get binding available in this on the view. There you will be using controller alias inside ng-controller directive & you should use dash to get controller binding.
<body ng-controller="dashboardCtrl as dash">
{{dash.something}}
</body>
Also make sure you have referred app.js on the page.
could you try in controller?
app.controller('dashboardCtrl', function($scope) {
$scope.something = "something";
});
For future references, I suggest to follow this great tip.
It's very useful because provide better readability and avoid make these kinds of mistakes.
I have an AngularJS document where I need to set fields in various parts of the document. This includes e.x. the <title> tag. So my document Looks like the following:
<html ng-app="test" ng-controller="TestCtrl">
<head>
<title>{{test1}}</title>
</head>
<body>
<h1>{{test1}}</h1>
...
</body>
</html>
As you can see I put the ng-controller in the <html> tag because I need to use the same scope across <head> and <body>. I could also set the controller on the individual elements but since I'm doing some POST and GET queries I think it's not a good idea because then they are performed multiple times.
Is using the ng-controller tag in the <html> element a good idea (is there a negative impact)? Are there better solutions?
I want to do an ng-repeat in the <head> of a page in order to enumerate open graph meta tags. However, I'm not sure how to accomplish as it seems that tags allowed in <head> are containing tags.
If I simply add a <div> wrapper like I often do with ng-repeat, browsers bump it down from the <head> down into <body>.
I have considered creating my own do-nothing directive to allow me to do something like this
<custom-repeat-wrapper ng-repeat="entry in entries">
<meta property="entry.key" content="entry.content"/>
</custom-repeat-wrapper>
I presume that would work, but for all I know, browsers might bump it down to <body> as well.
I guess I could potentially write my own directive that sorta works like ng-repeat, but doesn't require a wrapper, and instead duplicates the tag it is placed on.
Anyone have any other suggestions for a cleaner solution before I head down this path?
You would have to declare the angular app in the html tag and use the ng-repeat inside the meta tag, like this:
<html ng-app="myApp">
<head ng-controller="headController">
<meta ng-repeat="entry in entries" property ="{{entry.key}}" content="{{entry.content}}">
</head>
</html>
And the controller:
angular.module('myApp', [])
.controller('headController', function($scope) {
$scope.entries = [{
key: 'key1',
content: 'content1'
}, {
key: 'key2',
content: 'content2'
}, ];
})
Here is a working plunkr:
http://plnkr.co/edit/ztCTB4mhvyou4ccKVk0u?p=preview
I new in AngularJS. I am learning AngularJS. I am trying to follow different tutorials. I working with some codes now. I have a question in this regard. My codes ares as below
index.html
<html ng-app="main_app">
<head>
<title>AngularJS Application</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script src="js/route.js"></script>
</head>
<body ng-controller="main_controller">
<div ng-view></div>
</body>
</html>
route.js
var app = angular.module('main_app',['ngRoute']);
app.config(function($routeProvider)
{
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'main_controller'
});
});
app.controller('main_controller', function($scope)
{
alert('Yes');
});
If I run this code I get the alert('Yes'); twice.
Why I am getting this alert twice ?? Is it normal action or I am doing something wrong ??
Thanks
Update
#Leo Farmer I changed structure of index.html as belows
<html>
<head>
<title>AngularJS Application</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script src="js/route.js"></script>
</head>
<body>
<div ng-app="main_app">
<div ng-controller="main_controller">
<div ng-view></div>
</div>
</div>
</body>
</html>
But still I am getting alert() twice. Actually my concern is "Am I doing wrong or right ??" I think getting alert() twice means I am doing something wrong.
Is my structure following good convention ??
Thanks
Your controller is getting called twice. You have it in your body element (that's alert number one) then you also assign it as your controller for your pages/home.html which you call as your partial (that's alert two).
You don't need it in your body element. I recommend you take it out of there.
In my case, I have used <div id="userregistration" class="content-wrapper" ng-controller="UserRegistrationController"> in html and in $route also so it called twice. I removed in html after that it is fixed
I would reccomend modifying your alert code so it is triggered by a button or another event. You're seeing the asynchronous calling of a controller that, due to the times of which loading and processing your page, causes that code to be run twice.
I would first try loading your Javascript at the bottom of your body so that the entire page is loaded before JavaScript is.
Alternatively, you could try adding a timeout using the $timeout service to delay running your alert for a short time until the entire page loads.
Because:
You are using same controller in anguler route module and ng-controller directive in the template. If you use a controller in the route module while configuring, it is useless to use same controller with ng-controller in the template. ng-view directive is enough here.
Since you are using same controller both in route config and ng-controller, thats why you are getting alert twice. You should use your controller either in angular route or ng-controller directive
If you remove routing option, you will get alert only once.
Another AngularJS newbie question.
I've got an index.html, controllers, and partials.
My <body> tag is in the index.html ... and I want to set the class for the body in my controller.
So I tried sticking a value in $scope.body_class and then referencing that variable in my index.html, like this:
<!doctype html>
<html lang="en" ng-app="myGreatApp">
...
<body ng-class="{body_class}"> {{body_class}} Hi!
But body_class doesn't return a value.
How do I get body_class to return a value?
For starters, the controller has to be defined on the element or any parent element for it to be able to interact with the directives (or you will have to inject the $rootScope and use it instead) and, the ng-class directive accepts a hash, so
<body ng-controller="YourController" ng-class="{body_class: <expression>}"> {{body_class}} Hi!
and if <expression> is thruthy, it will get a html class that corresponds to the key in the hash.
<body ng-controller="YourController" ng-class="{body_class: true}" class="body_class"> whatever value $scope.body_class has Hi!
If you dont need to declare the class name in the markup, the ng-class directive also accepts a direct binding, so you can instead:
<body ng-controller="YourController" ng-class="body_class"> {{body_class}} Hi!
ng-class documentation
Try this:
Controller
function SampleCtrl($scope){
$scope.MyClass = 'Hello'
}
HTML
<body data-ng-app="" data-ng-controller='SampleCtrl'>
<div data-ng-class="MyClass">Hello World
</div>
</body>
Sample JsFiddle