Knockout JS foreach looping through array of objects - javascript

I have a observableArray:
self.stats = ko.observableArray([
{"DFTD" : new Stat("Defensive TD", "DFTD",0,20,0,self.playerGroups[1])},
{"GL" : new Stat("Games Lost", "GL",0,16,0,self.playerGroups[2])},
{"FGA" : new Stat("Field Goals ATT", "FGA",0,100,0,self.playerGroups[0])},
]);
and i am trying to loop around it with a foreach and then print out the Stat objects name property which is the first element in that object.
<tbody data-bind="foreach: stats" id="stat-sliders">
<tr>
<td><span data-bind="text: stats.Stat().name"></span></td>
<!--/*<td class="statsListItem">
</tr>
</tbody>
Im not sure if im doing it right. I am a beginner with knockout and wondering if anyone can help?

The fiddle below creates an array of football stats, which contains a key field and a stat field. You could use the key field for quicker access if you like. If you want an object where you have the property be the key, that would allow for the quickest indexing, though its not an array then.
See if this is what you want.
http://jsfiddle.net/johnpapa/CgFjJ/

You shouldn't need to call back into stats. Notice that the span binds to the property of the model that is inside the array.
<tbody data-bind="foreach: stats" id="stat-sliders">
<tr>
<td><span data-bind="text: name"></span></td>
<!--/*<td class="statsListItem">
</tr>
</tbody>
Also, I don't think Knockout works well with keyed arrays like that.

Related

How do I display an array / object using ng-repeat

I have an array that looks like the following:
I want to display that using angularJS ng-repeat, showing both count and value for each.
This is currently the HTML and angular I have but nothing displays.
I also don't need to display the 0 index in the array, I want to start from 1 if possible.
<tr ng-class="" ng-repeat="x in vm.data | filter: searchArray">
<td>{{x.value}}</td>
<td>{{x.count}}</td>
</tr>
I went back to the basics and understood that an ng-repeat is just a loop in javascript, and what do you need to do if you want to access data in JavaScript if your array is multi-dimensional? well you do a nested for loop, and thats exactly what I'm doing in this case.
This is the updated html/angularjs that displays the data I need:
<tbody>
<tr ng-repeat="x in vm.data">
<td ng-repeat="y in x">{{y.value}} {{y.count}}</td>
</tr>
</tbody>
Thank you guys again!

Angular bind table to generic object

I'm just starting to explore with Angular. Now what I'm trying to do is using an mvc handler that returns a jsonobject. However the returned jsonobject is generic, so it can be different types of object, and they all have a different amount of columns. I want to bind all these columns to a table, but that means i can't just create a fixed amount of columns and bind them like so:
<table class="table">
<tr ng-repeat="r in items">
<td>{{r.ID}}</td>
<td>{{r.Name}}</td>
<td>{{r.FirstName}}</td>
<td>{{r.Telephone}}</td>
<td>{{r.Email}}</td>
</tr>
</table>
this is NOT the way i want it, basically i want to have a table that binds to an object and that creates table columns for every property of the object.
thanks for any advice!
You can iterate the properties of the value like
<tr ng-repeat="r in items">
<td ng-repeat="(key, value) in r">
{{ value }}
</td>
</tr>

How to fix undefined property error in knockoutjs

Most of the time i get some error for 'undefined' property in knockout. I found a solution for the same on stackoverflow answer. It is effective for simple binding, but my question is that how would i use this technique for 'foreach' binding like i have tried like
Demo here
below code is not working
<table>
<tbody data-bind="foreach: model.mappings">
<tr>
<td>
<select data-bind="options:mappings.variableList, optionsText:'Key',optionsValue:'Value', value:mappings.selectedVariable>
</select>
</td></tr></tbody></table>
But below code is working
<table>
<tbody data-bind="foreach:mappings">
<tr>
<td>
<select data-bind="options:variableList, optionsText:'Key',optionsValue:'Value', value:selectedVariable>
</select>
</td></tr></tbody></table>
Js for both is same like:
var list = //some array
var arr =// [{variableList : list}];
var model={
mappings:ko.observableArray(arr)
}
ko.applyBindings......
Imagine your "model" being a function. When binding in html, you are able to access only local variables of model. Model itself is not visible because that is out of your scope. Mappings is a variable in model and that's why you can access it by just writing foreach: mappings. model is not part of model, it is model... Hope this helps.
Also, when you write foreach: mappings then you kind-of enter a foreach loop so that is why you don't write mappings.PropertyName and instead just write PropertyName
edit: my comment on your post was completely wrong so I deleted it

Change Index value in angular js

I am listing a json data in table format.Json contains different arrays and need to loop these arrays seperately.Everything working fine except the $index value.
Working Plunkr
Here i am looping each array in seperate tr.i need to get the index value updated like 1,2,3..
Any solutions??
If you necessarily needs to have them iterated as two different arrays you'll have to add the total number of members in the first array to the indexes for the second array, like this:
<!-- second tbody: -->
<tbody>
<tr ng-repeat="prioritymembers in Records.priorityMembers">
<td class="no" ng-bind="Records.stdMembers.length + $index+1"></td>
<td class="name" ng-bind="prioritymembers.members.fname"></td>
</tr>
</tbody>
Working plunker: http://plnkr.co/edit/1HiGoMuFAOTyOpD3SLoX?p=preview
Interesting proble, I don't think there is a straitforward solution.
You could do
<tr ng-repeat="prioritymembers in Records.priorityMembers">
<td class="no" ng-bind="$index + Records.stdMembers.length + 1"></td>
...
</tr>
Perhaps the cleaner solution would be to create a single array in the controller and iterate over that, instead of having 2 <body>s with separate iterations.

Failing to reevaluate property bound to table row knockout.js-style

I am failing to get a column updated from an array of objects loaded from the server.
I have got something like this:
self.tenants = ko.observableArray([{"Id":1,"Name":"Tenant 1","IsActive":true}]);
self.selectedTenant = ko.observable(null);
UI:
<tbody data-bind="foreach: tenants">
<tr data-bind="css: { 'active-row': $root.selectedTenant() === $data }">
<td>Select</td>
<td data-bind="text: Name"></td>
<td data-bind="text: Count"></td>
<td></td>
<td></td>
<td data-bind="text: IsActive"></td>
</tr>
</tbody>
Now I am trying to ensure the UI displays it when I set to IsActive to false.
I know that ideally IsActive is observable, but since I get the array straight from the server, I am not sure how I would do that.
Secondly I am somehow trying to get knockout to reevaluate the array.
I have tried several alternatives, one of which looks like this:
var selected = self.selectedTenant();
selected.IsActive = true;
var idx = self.tenants.indexOf(selected);
//self.tenants.remove(selected);
var newArray = self.tenants().splice(idx, 1, selected);
self.tenants(newArray);
//self.tenants.valueHasMutated();
But it all seems futile, the column always displays the original value. Where am I going wrong, or what should I do?
You need to map your server data to TenantViewModels thats using observables either manual or with the Ko mapping plugin
If you are doing it manual you can use the ko.utils.arrayMap function to map each element in the array from server to a new array with TenantViewModels

Categories