ng-repeat variable scope to the DOM block - angularjs

Am I dreaming or I really saw that somewhere, but I can't remember the exact syntax. So if I have
var fooObjects = [{ name:"John", age:15 },
{ name: "Michael", age:26 },
...etc...]
and
<div ng-repeat="for foo in fooObjects"> <-- note, this isn't real syntax
{{name}} <-- Now you don't have to explicitly call `foo.name`
{{age}} inside of this div block
</div>

An example from https://docs.angularjs.org/api/ng/directive/ngRepeat. Try something like this:
<div ng-init="friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]">
<ul>
<li ng-repeat="friend in friends">
{{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
Here's a plunker with the example http://plnkr.co/edit/I19oBk20T5ldLZe7GYqN?p=preview
--edit--
I misunderstood your earlier question. You could go about aliasing the variable in the ng-repeat by implementing the following in your controller:
$scope.scopify(scope, object) {
for (var o in object) {
scope[o] = object[o];
}
}
Used like the following:
<li ng-repeat="friend in friends" ng-init="scopify(this, friend)">
{{name}}, {{age}}, {{gender}}
</li>
Here is a plunker with a working example: http://plnkr.co/edit/Y8c4uOagcdM5cXN81TET?p=preview
In addition to the above example, you can create aliases for any of the properties of an object through the ng-init directive. For example, another possible solution could be this:
<li ng-repeat="friend in friends"
ng-init="name = friend.name; age = friend.age; gender = friend.gender">
{{name}}, {{age}}, {{gender}}
</li>
We can use ng-init to create aliases that we can reference in that html block. While this is not very useful if you are only going to reference each property once, it might come in handy if you have to repeat the same property multiple times within a block of html.

Related

AngularJS - object values not show in {{}}

I have to show some values from a Json in the {{}} but I see the values just are shown in console and right inside app.controller. Its just going off this app.controller and the values are not shown.
These are some parts of the code:
var app = angular.module('confusionApp',[]);
app.controller('dishDetailController', function() {
var dish={
name:'Uthapizza',
image: 'images/uthapizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comments: [
{
rating:5,
comment:"Imagine all the eatables, living in conFusion!",
author:"John Lemon",
date:"2012-10-16T17:57:28.556094Z"
},
{
rating:4,
comment....
And finishing:
...date:"2013-12-02T17:57:28.556094Z"
},
{
rating:2,
comment:"It's your birthday, we're gonna party!",
author:"25 Cent",
date:"2011-12-02T17:57:28.556094Z"
}
]
};
this.dish = dish;
console.log(dish["name"]); console.log(dish.image); console.log(dish.category);
console.log(dish.label); console.log(dish.price); console.log(dish.description);
console.log("----------------------------------------------------------");
console.log(dish.comments[0]["rating"]); console.log(dish.comments[0]["comment"]);
console.log(dish.comments[0]["author"]); console.log(dish.comments[0]["date"]);
});
console.log("Hey hey hey!");//This shown perfectly in console
console.log(dish.name);//but this is showing... ReferenceError: dish is not defined
And on the view it is not working too...Not is displayed, just blank.
....<img class="media-object img-thumbnail"
ng-src={{image}} alt="Uthappizza">
</a>
</div>
<div class="media-body">
<h2 class="media-heading">{{dish.name}}
<span class="label label-danger">{{dish.label}}</span>....
The ngApp is in html tag:
<html lang="en" ng-app="confusionApp">
And ngController is placed in a div that holds the entire view:
<div class="container" ng-controller="dishDetailController">
So...what's wrong?
You are using Controller as.
Just convert your
<div class="container" ng-controller="dishDetailController">
to
<div class="container" ng-controller="dishDetailController as ctrl">
and access value via ctrl
like this
{{ctrl.dish.name}}
use controller as in the html like this
<div ng-app="confusionApp" ng-controller="dishDetailController as vm">
<img class="media-object img-thumbnail"
ng-src={{vm.image}} alt="Uthappizza">
<div class="media-body">
<h2 class="media-heading">{{vm.dish.name}}
<span class="label label-danger">{{vm.dish.label}}</span>
</div>
var app = angular.module('confusionApp',[]);
app.controller('dishDetailController', function() {
var dish={
name:'Uthapizza',
image: 'images/uthapizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comments: [
{
rating:5,
comment:"Imagine all the eatables, living in conFusion!",
author:"John Lemon",
date:"2012-10-16T17:57:28.556094Z"
},
{
rating:2,
comment:"It's your birthday, we're gonna party!",
author:"25 Cent",
date:"2011-12-02T17:57:28.556094Z"
}
]
};
this.dish = dish;
console.log(dish["name"]); console.log(dish.image); console.log(dish.category);
console.log(dish.label); console.log(dish.price); console.log(dish.description);
console.log("----------------------------------------------------------");
console.log(dish.comments[0]["rating"]); console.log(dish.comments[0]["comment"]);
console.log(dish.comments[0]["author"]); console.log(dish.comments[0]["date"]);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="confusionApp" ng-controller="dishDetailController as vm">
<img class="media-object img-thumbnail"
ng-src={{vm.image}} alt="Uthappizza">
<div class="media-body">
<h2 class="media-heading">{{vm.dish.name}}
<span class="label label-danger">{{vm.dish.label}}</span>
</div>

ng-model into ui-gmap-marker

I need help to use ng-model directive with ui-gmap-marker. My example app.js is:
// DevicesController
$scope.devices = {
id: 1,
center: { latitude: X, longitude Y },
options: {
show: true,
name: 'device 1',
radius: 100
}
(...)
}
My index.html is:
<ul ng-controller="DevicesController">
<li ng-repeat="d in devices">
<input type="checkbox" ng-model="d.options.show">
<span>{{ d.options.name }}</span>
</li>
</ul>
(...)
<div id="map_canvas" ng-controller="DevicesController">
<ui-gmap-marker
ng-repeat="d in devicesMarkers track by d.id"
idkey="d.id"
coords="d.center"
ng-model="d.options.show">
</ui-gmap-marker>
(...)
How can I use ng-model? Doesn't work because I'm using the same controller e two different places? I want that the user be able to click in input checkbox and the marker appear/disappear.
I'd suggest simply wrap both the div in same controller rather than providing a separate controller to them.
Markup
<div ng-controller="DevicesController">
<ul>
<li ng-repeat="d in devices">
<input type="checkbox" ng-model="d.options.show">
<span>{{ d.options.name }}</span>
</li>
</ul>
(...)
<div id="map_canvas">
<ui-gmap-marker
ng-repeat="d in devicesMarkers track by d.id"
idkey="d.id"
coords="d.center"
ng-model="d.options.show">
</ui-gmap-marker>
</div>
(...)
</div>
Else maintain the data in share able service that will provide the data to both controller and will make sure, data should be updated in both places.

does ng-repeat create multiple instances of a variable?

I've created this plunker in the form of a 'ToDo' list. My purpose is to fulfill just what it looks like.
Click an item and it will become 'marked' complete. However I am seeing a weird occurrence happen and that is when I change the 'visible' variable to true or false on click, it only effects the list item in the ng-repeat. Conversely, in my 'ToDo' list without ng-repeat the behavior works as expected (though not as desired).
Why does it function this way?
(also the select element at the bottom would work, however it breaks the 'marking complete' by switching the value of 'visible' when I don't actually want it to, any ideas on that would be helpful as well)
http://plnkr.co/edit/uiirZNV5yyBuB5XLst6y?p=preview
<h2>using ng-repeat:</h2>
<div ng-init="peeps = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]"></div>
<ul ng-init="visible = true">
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}" ng-repeat="peep in peeps">{{peep.name}}</li>
</ul>
<h2>NOT using ng-repeat:</h2>
<div>
<ul ng-init="visible = true">
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[0].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[1].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[2].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[3].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[4].name}}</li>
<li ng-click="visible = !visible" ng-class="{'strike': !visible, 'none': visible}">{{peeps[5].name}}</li>
</ul>
this is because ng-repeat creates its own scope for each item,
you need to access parent scope via $parent
ng-repeat also gives you access to elemnt index in the array,
so your code may look like
ng-repeat="(i, peep) in peeps"
...
ng-click="$parent.peeps[i].visible = !$parent.peeps[i].visible"

Global value or cache for ng-repeat / ngRepeat in AngularJS

I'm trying to keep a global value or some sort of cache out of ngRepeat. It is a bit complicated to explain so here is what I'd like to do.
I used the example code from docs:ngRepeat.
<body>
<div ng-init="friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]">
<ul>
<li ng-repeat="friend in friends>
{{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
I want to sum up the age value on every repetition. The result should look like this:
John who is 25 years old. 25 - explanation: 25+0
Jessie who is 30 years old. 55 - explanation: 25+30
Johanna who is 28 years old. 83 - explanation: 55+28
Joy who is 15 years old. 98 - explanation: 83+15
...
A Plunkr for experiments can be found here http://plnkr.co/edit/VFiTOnmQ4cyqgNMDa9L4.
Thank you!
You could do something like:
<ul ng-init="ages = []">
<li ng-repeat="friend in friends">
{{friend.name}} who is {{friend.age}} years old.
{{ ages[$index] = (friend.age + ages[$index-1]) }}
- explanation {{friend.age }} + {{ 0 + ages[$index-1]}}
</li>
</ul>
Updated plunker: http://plnkr.co/edit/8XCt3j?p=preview

How do I render tree structure data by using directive's template

Have anyone tried to render tree structure data by using directive?
What I wanted to do is rendering the data like...
{
name: "root",
next: null,
child: {
name : "1"
next : {
name : "2",
next : {
name: "3",
next: null,
child: null
},
child: {
name: "2-1",
next: null,
child: null
}
},
child: {
name: "1-1",
next: {
name: "1-2",
next: null,
child: null
},
child: null
}
}
}
to HTML data like
<ul>
<li> root
<ul>
<li> 1
<ul>
<li> 1-1 </li>
<li> 1-2 </li>
</ul>
</li>
<l1> 2
<ul>
<li> 2-1 </li>
</ul>
</li>
<li> 3 </li>
</ul>
</li>
</ul>
I know if data is an array, I can use "ng-repeat" for template,
and also if data is an object I know the structure, I can use "{{ }}" tag.
But I don't have any idea for treating object data will change dynamically.
That means I also want to add some child to the data as one object in $scope,
and render it synchronously using angular.js .
Does anyone have a great idea or the experience you did it?
angularjs
<div ng-init="friends = [
{name:'John', age:25, gender:'boy'},
{name:'Jessie', age:30, gender:'girl'},
{name:'Johanna', age:28, gender:'girl'},
{name:'Joy', age:15, gender:'girl'},
{name:'Mary', age:28, gender:'girl'},
{name:'Peter', age:95, gender:'boy'},
{name:'Sebastian', age:50, gender:'boy'},
{name:'Erika', age:27, gender:'girl'},
{name:'Patrick', age:40, gender:'boy'},
{name:'Samantha', age:60, gender:'girl'}
]">
<ul class="example-animate-container">
<li class="animate-repeat" ng-repeat="friend in friends | filter:q">
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
result
[1] John who is 25 years old.
[2] Jessie who is 30 years old.
[3] Johanna who is 28 years old.
[4] Joy who is 15 years old.
[5] Mary who is 28 years old.
[6] Peter who is 95 years old.
[7] Sebastian who is 50 years old.
[8] Erika who is 27 years old.
[9] Patrick who is 40 years old.
[10] Samantha who is 60 years old.

Resources