Reputation: 509
Basically I am trying to two-way bind to a table of values based on the intersection of point in the table.
I've set up a plnkr of what I am trying to achieve here...
So given this set of data...
$scope.beers = [
{ id: 27, description: "Hopslam Ale" },
{ id: 28, description: "Founders Kentucky Breakfast Stout" },
{ id: 29, description: "Zombie Dust" } ];
$scope.characteristics = [
{ id: 3, description: "ABV" },
{ id: 4, description: "IBU" },
{ id: 5, description: "Calories" },
{ id: 6, description: "Reviews"}];
$scope.crossData = [
{ beerId: 27, characteristicId: 3, value: 10 },
{ beerId: 27, characteristicId: 4, value: 70 },
{ beerId: 27, characteristicId: 5, value: 300 },
{ beerId: 27, characteristicId: 6, value: 3419 },
{ beerId: 28, characteristicId: 3, value: 11 },
{ beerId: 28, characteristicId: 4, value: 70 },
{ beerId: 28, characteristicId: 5, value: 336 },
{ beerId: 28, characteristicId: 6, value: 2949 },
{ beerId: 29, characteristicId: 3, value: 6 },
{ beerId: 29, characteristicId: 4, value: 50 },
{ beerId: 29, characteristicId: 5, value: 186 },
{ beerId: 29, characteristicId: 6, value: 1454 }];
How can I two-way bind to the value in the cross data?
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th ng-repeat="char in characteristics">
{{ char.description }}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="beer in beers">
<td>{{ beer.description }}</td>
<td ng-repeat="char in characteristics">
<!-- some kind of binding expression here -->
</td>
</tr>
</tbody>
</table>
Any help would be greatly appreciated.
Upvotes: 1
Views: 3031
Reputation: 5535
Sorry for my last answer. I did not notice the two way data bind need.
So, I've found two solutions
1 - This one filter the crossData on the html: http://plnkr.co/edit/M1rnx6IJqJ95apJJ55iN
<tbody>
<tr ng-repeat="beer in beers">
<td>{{ beer.description }}</td>
<td ng-repeat="char in characteristics">
<input ng-model="(crossData | filter:{beerId: beer.id, characteristicId: char.id})[0].value"/>
</td>
</tr>
</tbody>
2 - This one uses a function to filter the crossData: http://plnkr.co/edit/MHQy31rqZMg2TXYn0P23
What I did was Add a function to return the object of the crossData list. The function is as follow:
$scope.getCrossDataRow = function(beerId, charId){
return $filter('filter')($scope.crossData, {beerId: beerId, characteristicId: charId})[0];
};
Do not forget to load the $filter in your controller.
Finally, you can use this function in your table row to bind the value as follow:
<td ng-repeat="char in characteristics">
<input type="text" ng-model="getCrossDataRow(beer.id, char.id).value" />
</td>
Upvotes: 1
Reputation: 1040
You could do this with this expression:
<span ng-repeat="cross in crossData" ng-if="cross.beerId === beer.id && cross.characteristicId === char.id">{{cross.value}}</span>
But it would be better if you had another data structure, but i guess you have no influence on this?
Upvotes: 0
Reputation: 5792
You can write a 'matching' function in the controller like this (current implementation just returns the first match):
$scope.findMatch = function(beer, characteristic) {
return $scope.crossData.filter(function(data) {
return data.beerId === beer.id && data.characteristicId === characteristic.id
})[0];
}
Working code snippet:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.beers = [
{ id: 27, description: "Hopslam Ale" },
{ id: 28, description: "Founders Kentucky Breakfast Stout" },
{ id: 29, description: "Zombie Dust" } ];
$scope.characteristics = [
{ id: 3, description: "ABV" },
{ id: 4, description: "IBU" },
{ id: 5, description: "Calories" },
{ id: 6, description: "Reviews"}];
$scope.crossData = [
{ beerId: 27, characteristicId: 3, value: 10 },
{ beerId: 27, characteristicId: 4, value: 70 },
{ beerId: 27, characteristicId: 5, value: 300 },
{ beerId: 27, characteristicId: 6, value: 3419 },
{ beerId: 28, characteristicId: 3, value: 11 },
{ beerId: 28, characteristicId: 4, value: 70 },
{ beerId: 28, characteristicId: 5, value: 336 },
{ beerId: 28, characteristicId: 6, value: 2949 },
{ beerId: 29, characteristicId: 3, value: 6 },
{ beerId: 29, characteristicId: 4, value: 50 },
{ beerId: 29, characteristicId: 5, value: 186 },
{ beerId: 29, characteristicId: 6, value: 1454 }];
$scope.name = 'Stack Overflow friends';
$scope.findMatch = function(beer, characteristic) {
return $scope.crossData.filter(function(data) {
return data.beerId === beer.id && data.characteristicId === characteristic.id
})[0];
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<br />
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th ng-repeat="char in characteristics">
{{ char.description }}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="beer in beers">
<td>{{ beer.description }}</td>
<td ng-repeat="char in characteristics">
{{findMatch(beer, char).value}}
</td>
</tr>
</tbody>
</table>
</body>
Upvotes: 0