How to change scope when controller is changed using Angular routes without using $rootScope - angularjs

https://plnkr.co/edit/U9tL95qS5AgsPu6nNwVD/
I am able to change ng-view with templateUrl. But it is not updating {{msg}} when I am updating it using $scope.msg in every new controller.
Is there a way to update it without using $rootscope. Since I have heard that $rootScope practise is bad.
I guess I Am not registering the controller ??
I am new to Angular.
I dont know how to use services
in index.html
app.controller("redCtrl", ['$scope', '$route', function($scope, $route) {
$scope.msg = "I love red"; //NOT WORKING **************
}]);

check out this plnkr https://plnkr.co/edit/rvIZouNydPpwFgsIiVaf
#Rohitas Behera The reason is simple you are using
<div ng-app="myApp" ng-controller="mainController">
<p>Main</p>
Red
Green
Blue
<div ng-view>
</div>
{{msg}} <!-- why using here !>
</div>
so this time the msg is in scope of maincontroller . There are not other controller in scope
To do so remove {{msg}} from index.html and place it in there respective page.
Like this.
blue.html
<div style="background-color:#2196f3;">
<h1>Blue {{msg}}</h1>
</div>
same for all html page.

To alter the value {{msg}} in different context/controller, you will need to write {{msg}} in individual .html files where you have set the scope of respective controller.
As of now the variable is accessible only to your mainController as it is seen in index.html only, hence the value never changes.
You need to remove it from index.html and put it in every html.
here is the fixed plunkr

you have to add {{msg}} in every template.like this
<div style="background-color:#f44336;">
<h1>Red</h1>
{{msg}}
</div>
and remove {{msg}} form index.html page because maincontroller is working for index page and the modified page like this
<div ng-app="myApp" ng-controller="mainController">
<p>Main</p>
Red
Green
Blue
<div ng-view>

Related

AngularJS - How to add an app in a particular state to a HTML element

So lets say my app is called myApp, and the controller I wanna use is MyCtrl. So I can include this app in a div tag like this:
<div ng-app="myApp" ng-controller="MyCtrl">
</div>
Lets say there are a few states, and usually I would use the router to map the states to the URL like this: http://example.com/state1 or http://example.com/state2.
If I wanna include this app in state2 into the div tag, is there a way to do this? I'm kinda new to angular, basically I wanna be able to build a page that includes pieces of different modules into different parts of the page.
You will want to user ui-router for that. Specifically, you will use the ui-view directive to specify where a state's template goes into it's parent template, or the page.
you can use ng-include: Fetches, compiles and includes an external HTML fragment.
From Angular docs: AngularJS API
<div ng-controller="ExampleController">
<select ng-model="template" ng-options="t.name for t in templates">
<option value="">(blank)</option>
</select>
url of the template: <code>{{template.url}}</code>
<hr/>
<div class="slide-animate-container">
<div class="slide-animate" ng-include="template.url"></div>
</div>
</div>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ui-view>
//here goes your states
</div>
</div>
// inject $stateProvider in your module and config function like:
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider.state("home.state1",{
url:"home/state1"
templateUrl:templatename.html,
controller:MyCtrl,
}).state("home.state2",{
url:"home/state2"
templateUrl:templatename.html,
controller:MyCtrl,
});
})

Pass variable from controller to another controller via rootScope

im working on a project, and I'm having difficulties passing a variable from a MainController to NavbarController, via rootScope.
Angular doesnt print the {{windowName}} variable that i pass from MainController to NavbarController via $rootScope.
So this is the code that im using:
View:
<body>
<nav ng-controller="NavbarController">
<ul>
<li>{{windowName}}</li>
</ul>
</nav>
<!-- this is where i use ng-view instead of MainController -->
<div ng-controller="MainController">
{{name}}
</div>
</body>
Controller:
var myApp = angular.module('myApp',[]);
function MainController($scope, $rootScope){
$rootScope.windowName = 'Window name 95';
$scope.name = 'Test name';
}
function NavbarController($scope, $rootScope){
$scope.windowName = $rootScope.windowName;
}
Filddle: http://jsfiddle.net/6v0fx6d2/1/
Explanation:
I'm using ngRoute, so i simplified the code, in the comment is where i use ng-view, to render the templates, so the navbar is the Basic Template that I'm using.
if you change your html structure it will work.
<div ng-controller="MainController">
{{name}}
</div>
<nav ng-controller="NavbarController">
<ul>
<li>{{windowName}}</li>
</ul>
</nav>
In angularjs the controllers are executed in the order they appear in the code.So in your case the windowName is not set. So it isn't available in NavbarController
Okay i found the problem.
To print a rootScope variable you need to add {{$route.windowName}} .
Also if you use ExpressJS with HoganTemplate, make sure you change
Hogan mustache brackets with this:
app.locals.delimiters = '{{{ }}}';

Angularjs | how to get an attribute value from element in which controller is defined

I'm still fighting with simple things in Angular. I have jQuery and Backbonejs background, so please do not yell on me. I try hard to understand differences
I have HTML in which from rails is given ID of project as data-project-id:
<div data-ng-controller="ProjectCtrl as ctrl" data-project-id="1" id="project_configuration">
Is there any chance to get access to this attribute? I need it to my API calls...
To access an elements attributes from a controller, inject $attrs into your controller function:
HTML
<div test="hello world" ng-controller="ctrl">
</div>
Script
app.controller('ctrl', function($attrs) {
alert($attrs.test); // alerts 'hello world'
});
In your example, if you want to get data-project-id:
$attrs.projectId
Or if you want to get id:
$attrs.id
Demo:
var app = angular.module('app',[]);
app.controller('ctrl', function($attrs) {
alert($attrs.test);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl" test="hello world">
</div>
In Angular world you should use directives to manipulate with DOM elements. Here a nice explanation how to get attribute value from custom directive (How to get evaluated attributes inside a custom directive).
But if you still want to get it's value from controller you are able to use jQuery as well $('#project_configuration').data('project-id')

AngularJS - How to make SPA with multiple sections

I have the following basic breakdown of my layout:
<body>
<div id="left"></div>
<div id="content" ng-view></div>
<div id="right"></div>
<body>
I use ng-view in the main content to load the content dynamically through $routeProvider and templateUrl. However, the content in #left and #right also sometime need to change depending on what page I go to.
What's the best way to add/remove elements to #left and #right dynamically? I would basically want that if I load /view1 with controller View1Controller, then if this view has extra components, then I can display them within View1Controller.
In order to do this sort of requirement (without any extra plugins) you'll have to pull your left and right views out into their own view and set each route's main view to include left, content, and right themselves.
Example:
<!-- Core Html-->
<body ng-app>
<div ng-controller="MainCtrl" ng-view></div>
</body>
MainCtrl.js
angular.module('MyApp').controller('MainCtrl', function($scope){
$scope.defaults = {
leftView: "views/view1.html",
rightView: "views/view2.html"
}
});
Route /view1 and it's main view (call it view1.html)
<div ng-controller="View1Ctrl">
<div id="left" ng-include="defaults.leftView"></div>
<div id="content" ng-include="contentView"></div>
<div id="right" ng-include="defaults.rightView></div>
</div>
View1Ctrl
angular.module('MyApp').controller('View1Ctrl', function($scope){
$scope.contentView = "views/view1/firstPanel.html";
//Add some other functions to change $scope.contentView to say
//"views/view1/secondPanel.html"
//You could also temporarily replace $scope.defaults.leftView
//and rightView to show the View1 route in full screen so to speak. like so
$scope.setFullPanel = function(){
$scope.defaults.leftView = ''; //or something else
$scope.defaults.rightView = '';
$scope.contentView = "views/view1/fullScreenPanel.html";
}
});
Route /view2 and it's main view (call it view2.html)
<div ng-controller="View2Ctrl">
<div id="left" ng-include="defaults.leftView"></div>
<div id="content" ng-include="contentView"></div>
<div id="right" ng-include="defaults.rightView></div>
</div>
View2Ctrl
angular.module('MyApp').controller('View2Ctrl', function($scope){
$scope.contentView = "views/view2/firstPanel.html";
//Add some other functions to change $scope.contentView to say
//"views/view2/secondPanel.html"
});
Now that you have the routes and views setup for default left and right panels you could setup a route for a panel with no left and right for example:
<div ng-controller="View3Ctrl">
<div id="content" ng-include="contentView"></div>
</div>
View3Ctrl
angular.module('MyApp').controller('View3Ctrl', function($scope){
$scope.contentView = "views/view3/wholeScreenPanel.html";
});
Hope this helps. Also it's important for "scope hierarchy reasons" to ensure the higher level "default" variables are saved on $scope.defaults so any changes in View1Ctrl or View2Ctrl to $scope.defaults will be properly update throughout all your controllers / views.
I do not completely understand your requirement but did you take a look of the ui-router from angular-ui. Link: http://angular-ui.github.io/ui-router/.
Btw, you can see sample app here: http://angular-ui.github.io/ui-router/sample/#/ Hope it helps.

Simple AngularJS running on JSFiddle

How do I make a jsfiddle out of the following code:
<html>
<head>
</head>
<body>
<div ng-app ng-controller="MainCtrl">
<ul>
<li ng-repeat="num in nums">
{{num}}
</li>
</ul>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
<script type="text/javascript" charset="utf-8">
function MainCtrl($scope) {
$scope.nums = ["1","2"];
}
</script>
</body>
</html>
My non working attempt: http://jsfiddle.net/zhon/3DHjg/ shows nothing and has errors.
You need to set some things up in jsFiddle for this to work.
First, on the left panel, under "Frameworks & Extensions", select "No wrap - in <body>".
Now, under "Fiddle Options", change "Body tag" to <body ng-app='myApp'>
In the JS panel, initiate your module:
var app = angular.module('myApp', []);
Check it out: http://jsfiddle.net/VSph2/1/
#pkozlowski.opensource has a nice blog post about how to use jsFiddle to write AngularJS sample programs.
You've defined your controller in a function scope that is not accessible to angular (angular is not yet loaded). In other words you are trying to call angular library's functions and helpers like below example before getting angular library loaded.
function onload(){
function MainCtrl(){}
}
To resolve this, switch your angular load type to be No wrap - in <body> like shown in screenshot.
here is a working example in jsfiddle
Click JAVASCRIPT button, choose angular version and place where u want include loaded script:
Then click HTML button and add ng-app in body tag. Its all:)
I am writing my answer for those who land on this page , I was used to use ng-module directive but in jsfiddle after half an hour I realized that ng-module is not allowed and you see no error , and when changed that ng-module to ng-app fiddle worked very well .I just wanted to share this .And no wrap (body) is required too.
<div ng-app="appX" ng-controller="appCtrl">
<p>{{greeting}}
</p>
</div>
var app=angular.module("appX",[]);
console.log(app);
app.controller("appCtrl",function($scope){
$scope.greeting="Hello World";
});
https://jsfiddle.net/cloudnine/trgrjwf1/7/
Since Angular 1.4.8 has been chosen by JSFiddle as the top option for Angular V1 in its JAVASCRIPT setting panel, more restriction applies: both ng-app and ng-controller should be declared in HTML to make it work.
Sample HTML:
<div ng-app="myApp" ng-controller="myCtrl">
<input type="text" ng-model="sample" placeholder="type something here...">
<span>{{sample}}</span>
</div>
Sample JS:
angular.module('myApp', [])
.controller('myCtrl', function($scope) {});
https://jsfiddle.net/y170uj84/
Also tested with the latest Angular 1.6.4, by setting as External Resource.
For little experiments in angular 5, you can use https://stackblitz.com/.
This site is used in angular documentation to run live demo. For example, https://stackblitz.com/angular/eybymjopmav

Resources