Initializing scope variables in controllers - javascript

So I am completely new to AngularJS and followed a course and started "learning" this framework. I watched the 2 screencasts at the top of this page:
https://github.com/curran/screencasts/tree/gh-pages/introToAngular
After watching both screencasts and looking into some of the examples I tried to create my own simple Angular application where I tried to work with some controllers. Now I have the following code:
Index.html
<html ng-app="WIMT">
<head>
<title>trying out angularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script type="text/javascript" src="../bower_components/angular/angular.min.js"></script>
<script type="text/javascript" src="../JS/app.js"></script>
</head>
<body>
<div ng-controller="controllerA as a">
{{a.varA}}
</div>
<div ng-controller="controllerB as b">
{{b.varB}}
</div>
<div ng-controller="controllerC as c">
{{c.varC}}
</div>
</body>
</html>
JS
(function() {
var app = angular.module('WIMT',[]);
app.controller('controllerA',function($scope,$http){
$scope.varA = "A";
});
app.controller('controllerB',['$scope',function($scope) {
$scope.varB = "B";
}
]);
app.controller('controllerC',function($scope, $http) {
var reg = this;
reg.varC = "C";
});
})();
After I tried to bind varA to the scope in controller A I found out that it didn't work and I looked for a solution on the internet. I have found a few different ways (B & C) that should (could?) work. Only option C works and shows C when I run the html. Both A & B show nothing.
Why do option A and B not work in this example?

Because you are using controllerAs syntax, that's why the third one is working and first two are not.
<div ng-controller="controllerA as a">
{{a.varA}}
</div>
<div ng-controller="controllerB as b">
{{b.varB}}
</div>
<div ng-controller="controllerC as c">
{{c.varC}}
</div>
If you want the a.varA and b.varB to print, you have to change to below:
<div ng-app="app">
<div ng-controller="controllerA as a">
{{varA}}
</div>
<div ng-controller="controllerB as b">
{{varB}}
</div>
<div ng-controller="controllerC as c">
{{c.varC}}
</div>
</div>
http://jsfiddle.net/t0hhp5wz/

this is pretty the same thing :
app.controller('controllerA',function($scope,$http){
$scope.varA = "A";
});
this syntax will work if you use minification, the previous not.
app.controller('controllerB',['$scope',function($scope) {
$scope.varB = "B";
}
]);
use this syntax in the view :
<div ng-controller="controllerA">
{{varA}}
</div>

since you are using controller as alias, option A & B are placed inside controller scopes which are childScopes of $scope.
if you console.log the $scope you will see option A & B created inside controller scope and not in $scope which is parent scope for those controllers.

Related

Change div content dynamically on ng-click AngularJS

I want to display some data and tables in the content div which depends on which category you choose on the left hand side navigation.
So if I change the category also the displayed content of the content div should change.
Here is my code on Plunkr.
But it seems that not even this simple example is working.
So I have two Questions:
1.) How can I fix this example code to run ?
But more important:
2.) Is there a better way to change the content div when you change the category ?
I removed 'this' elements from code and also changed ng-view to ng-show.
<div>
<div ng-show="showApple">{{content}}</div>
<div ng-show="showBanana">{{content}}</div>
<div ng-show="showOrange">{{content}}</div>
</div>
There was something wrong with that you named your div class "content" so I removed that also.
I am sure it isn't a perfect solution but now it works.
link to plnkr
To be honest your best bet is to use $states/views. With a data-ui-view on the content div and a data-ui-sref link on the button on your menu, you can easily switch out content. Take a look at the ui-router page to get a better understanding of it. With templates for each 'view' that your menu will click to, your code will not just be much easier to manage, but probably more understandable.
You can use ng-include to show your contents but you have to keep them in seperate files e.g contentForApple, contentForBanana and contentForOrange.
Here I can show you a little change in your div
<div class="content">
<div ng-show="MainCtrl.showApple" ng-include ="'contentForApple.html'"></div>
<div ng-show="MainCtrl.showBanana" ng-include = "'contentForBanana.html'"></div>
<div ng-show="MainCtrl.showOrange" ng-include = "'contentForOrange.html'"></div>
</div>
Hope this help you. Take one json array for category and data and get details of json data which index is clicked
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="MyController">
<div class="container">
<div class="row">
<div class="col-lg-3">
<ANY ng-repeat="x in category" ng-click="getData($index)">
{{x.category}}<br>
</ANY>
</div>
<div class="col-lg-6">
{{data}}
</div>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('MyController', function ($scope)
{
$scope.data = '';
$scope.category = [{category:'Apple',data:'Apple Data'},{category:'Banana',data:'Banana Data'},{category:'Orange',data:'Orange Data'}];
$scope.getData = function(index)
{
$scope.data = $scope.category[index]['data'];
}
});
</script>
</body>
</html>
I did it with simple ngif
1) Keep an Index of Page which needs to be is loaded now
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.pageIndex = 0;
/*
* Updates current Page index
*/
$scope.changeIndex= function(indexToChange){
$scope.pageIndex = indexToChange;
}
});
2) Load content based on selected index
<body ng-controller="MainCtrl">
<div class="mainframe">
<div class="navigation">
<ul class="list-group">
<li class="list-group-item" ng-click="changeIndex(0)">Home<span class="status-icon"></span></li>
<li class="list-group-item" ng-click="changeIndex(1)">Sign Up<span class="status-icon"></span></li>
<li class="list-group-item" ng-click="changeIndex(2)">About<span class="status-icon"></span></li>
</ul>
</div>
<div class="content">
<div ng-if="pageIndex == 0" ng-include ="'Home.html'"></div>
<div ng-if="pageIndex == 1" ng-include = "'SignUp.html'"></div>
<div ng-if="pageIndex == 2" ng-include = "'About.html'"></div>
</div>
</div>
Final Result:
https://embed.plnkr.co/ic0eY2vwiOnChN2ahrEt/

Using Two Controllers in a Single AngularJS App

Full source code can be found http://plnkr.co/edit/rQSg5eMhm9uc9dSWnWEU?p=preview
In the index.html file if I use only one controller at a time it works. That is if I use
<body>
<div id="inputExample" ng-app="AngularJSTestBedWebApp" ng-controller="AngularJSInputExampleController">
input example: <input type="text" ng-model="inputValue" /><br/>
This is the updated value: {{inputValue}}
</div>
</body>
or if I use
<body>
<div id="scopeExample" ng-app="AngularJSTestBedWebApp" ng-controller="AngularJSScopeExampleController">
{{understandingScope}}
</div>
</body>
It will also work. However if I use both controllers at the same time such as
<body>
<div id="scopeExample" ng-app="AngularJSTestBedWebApp" ng-controller="AngularJSScopeExampleController">
{{understandingScope}}
</div>
<div id="inputExample" ng-app="AngularJSTestBedWebApp" ng-controller="AngularJSInputExampleController">
input example: <input type="text" ng-model="inputValue" /><br/>
This is the updated value: {{inputValue}}
</div>
</body>
The second controller never gets used. {{inputValue}} never gets assigned a default value and also never updates when you type in the text box. It literally just says "{{inputValue}}" the entire time.
I'm sure this is probably something easy but I'm very new to AngularJS. Thanks in advance for any help.
The ng-app attribute should be placed at the root of the application. In your example that would be <body/> or <html/>
<body ng-app="AngularJSTestBedWebApp">
<div id="scopeExample" ng-controller="AngularJSScopeExampleController">
{{understandingScope}}
</div>
<div id="inputExample" ng-controller="AngularJSInputExampleController">
input example: <input type="text" ng-model="inputValue" /><br/>
This is the updated value: {{inputValue}}
</div>
</body>
Updated plnkr
Here a complete example of two applications in one html page and two conrollers in one application :
<div ng-app = "myapp">
<div ng-controller = "C1" id="D1">
<h2>controller 1 in app 1 <span id="titre">{{s1.title}}</span> !</h2>
</div>
<div ng-controller = "C2" id="D2">
<h2>controller 2 in app 1 <span id="titre">{{s2.valeur}}</span> !</h2>
</div>
</div>
<script>
var A1 = angular.module("myapp", [])
A1.controller("C1", function($scope) {
$scope.s1 = {};
$scope.s1.title = "Titre 1";
});
A1.controller("C2", function($scope) {
$scope.s2 = {};
$scope.s2.valeur = "Valeur 2";
});
</script>

Pass parameter to Angular ng-include

I am trying to display a binary tree of elements, which I go through recursively with ng-include.
What is the difference between ng-init="item = item.left" and ng-repeat="item in item.left" ?
In this example it behaves exactly the same, but I use similiar code in a project and there it behaves differently. I suppose it's because of Angular scopes.
Maybe I shouldn't use ng-if, please explain me how to do it better.
The pane.html is:
<div ng-if="!isArray(item.left)">
<div ng-repeat="item in [item.left]" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.left)">
{{item.left[0]}}
</div>
<div ng-if="!isArray(item.right)">
<div ng-repeat="item in [item.right]" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.right)">
{{item.right[0]}}
</div>
<div ng-if="!isArray(item.left)">
<div ng-init = "item = item.left" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.left)">
{{item.left[0]}}
</div>
<div ng-if="!isArray(item.right)">
<div ng-init="item = item.right" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.right)">
{{item.right[0]}}
</div>
The controller is:
var app = angular.module('mycontrollers', []);
app.controller('MainCtrl', function ($scope) {
$scope.tree = {
left: {
left: ["leftleft"],
right: {
left: ["leftrightleft"],
right: ["leftrightright"]
}
},
right: {
left: ["rightleft"],
right: ["rightright"]
}
};
$scope.isArray = function (item) {
return Array.isArray(item);
}
});
EDIT:
First I run into the problem that the directive ng-repeat has a greater priority than ng-if. I tried to combine them, which failed. IMO it's strange that ng-repeat dominates ng-if.
It's a little hacky, but I am passing variables to an ng-include with an ng-repeat of an array containing a JSON object :
<div ng-repeat="pass in [{'text':'hello'}]" ng-include="'includepage.html'"></div>
In your include page you can access your variable like this:
<p>{{pass.text}}</p>
Pass parameter to Angular ng-include
You don't need that. all ng-include's sources have the same controller. So each view sees the same data.
What is the difference between ng-init="item = item.left" and ng-repeat="item in item.left"
[1]
ng-init="item = item.left" means - creating new instance named item that equals to item.left. In other words you achieve the same by writing in controller:
$scope.item = $scope.item.left
[2]
ng-repeat="item in item.left" means create list of scopes based on item.left array. You should know that each item in ng-repeat has its private scope
I am trying to display a binary tree of elements, which I go through recursively with ng-include.
I posted in the past answer how to display tree by using ng-include.
It might helpful: how-do-display-a-collapsible-tree
The main part here that you create Node with id wrapped by <scipt> tag and use ng-repeat:
<script type="text/ng-template" id="tree_item_renderer">
<ul class="some" ng-show="data.show">
<li ng-repeat="data in data.nodes" class="parent_li" ng-include="'tree_item_renderer'" tree-node></li>
</ul>
</script>
<ul>
<li ng-repeat="data in displayTree" ng-include="'tree_item_renderer'"></li>
Making a generic directive instead of ng-include is a cleaner solution:
Angular passing scope to ng-include
I am using ng-include with ng-repeat of an array containing string. If you want to send multple data so please see Junus Ergin answer.
See my code Snippet:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
<div ng-repeat="name in ['Sanjib Pradhan']" ng-include="'your_template.html'"></div>
<div ng-repeat="name in ['Chinmay Sahu']" ng-include="'your_template.html'"></div>
<script type="text/ng-template" id="your_template.html">
{{name}}
</script>
</div>

Model does not update within ng-if

I've got a strange behavior in an angular application and I don't know if that's a bug or a known limitation:
'use strict';
var ctrl = function ($scope) {
$scope.foo = false;
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="ctrl">
foo: {{foo}}
<div ng-if="foo" style="background-color: #f00;">
<p>foo</p>
</div>
<div ng-if="!foo">
<br/><button ng-click="foo = true;">Show foo</button>
</div>
<button ng-click="foo = true">Show foo</button>
</div>
http://jsfiddle.net/78R52/
I would expect that clicking one of the buttons would set foo = true, but clicking the first button (within the ng-if="!foo") doesn't change the model.
Tested version is 1.2.1.
ng-if has its own scope, so you need to use:
<br/><button ng-click="$parent.foo = true;">Show foo</button>
Updated fiddle: http://jsfiddle.net/78R52/1/
Ah, ng-if creates a new scope! So, "there has to be a dot in the model name"!
http://jsfiddle.net/78R52/2/
As others have said, ng-if has its own scope.
What i want to say, it's a bad practice to put expressions in the view. The good practice is to have a scope function that's called within the view.
var ctrl = function($scope){
$scope.foo = false;
$scope.fn = fn;
function fn(){
$scope.foo = true;
}
/////
<div ng-app ng-controller="ctrl">
foo: {{foo}}
<div ng-if="foo" style="background-color: #f00;">
<p>foo</p>
</div>
<div ng-if="!foo">
<br/><button ng-click="fn()">Show foo</button>
</div>
<button ng-click="fn()">Show foo</button>
</div>

angular.js how to alter variable value step by step

Here is my html code
<div ng-app='app'>
<div ng-controller="MyController" ng-init="myVar=7">
{{myVar}}
<span ng-init="myVar=myVar+5">{{myVar}},</span>
<span ng-init="myVar=myVar+15">{{myVar}},</span>
<span ng-init="myVar=myVar+37">{{myVar}},</span>
</div>
and script
var app = angular.module('app',[]);
app.controller('MyController', function() {});
The output I'm getting is 64,64,64,64
but I want output as 7,12,27,64
I'm trying to find things like ng-repeat but I cant kept these in an array
In every ng-init you're altering the value of myVar that is data bound to all other instances; and that's why they all show the same. So rather do:
<div ng-app='app'>
<div ng-controller="MyController" ng-init="myVar=7">
{{myVar}}
<span>{{myVar+5}},</span>
<span>{{myVar+15}},</span>
<span>{{myVar+37}},</span>
</div>

Categories

Resources