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"
Related
I would like to display a list based on which item is selected in a dropdown.
When I use the code below, I'm getting this error:
TypeError: Cannot read property 'type' of undefined
Any suggestions on how to do this right?
HTML:
<select class="form-control" ng-model="editProject.project.type"
ng-options="project as project.type for project in editProject.options track by project.type">
</select>
<ul class="list-group">
<li class="list-group-item" ng-repeat="benefit in editProject.foods()">{{snack}}</li>
</ul>
Controller:
.controller('EditProjectCtrl', function () {
var editProject = this;
editProject.options = [
{'type': 'Fruits'},
{'type': 'Vegetables'},
{'type': 'Desserts'}
];
editProject.snacks = function() {
if(editProject.project.type == 'Fruits') {return [
'Grapes',
'Oranges',
'Apples',
]}
if(editProject.project.type == 'Vegetables') {return [
'Broccoli',
'Spinache',
'Kale',
]}
else {return [
'Cookies',
'Cake',
'Pie']}
};
You are almost there. There was a mismatch between the ng-model of the select element, and the conditions in the controller. I also replaced benefit in editProject.foods() with snack in editProject.snacks():
<select class="form-control" ng-model="editProject.project" ng-options="project as project.type for project in editProject.options track by project.type"></select>
<ul class="list-group">
<li class="list-group-item" ng-repeat="snack in editProject.snacks()">{{snack}}</li>
</ul>
Because editProject.project is not defined until you select a project, you have to initialize it in the controller:
editProject.project = {};
See fiddle
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.
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.
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
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.