Reputation: 51928
I have an object that looks like:
var obj = [
[{x:3,y:3},{x:6,y:1},{x:3,y:5}],
[{x:1,y:3},{x:6,y:1},{x:3,y:5}],
[{x:3,y:3},{x:6,y:1},{x:3,y:5}]
]
Now I'd like to bind this in angular. But on the page I just want it to look like a bunch of divs (but with no nested div structures). So:
<div style='position:absolute; left:3px;top:3px'></div>
<div style='position:absolute; left:6px;top:1px'></div>
<div style='position:absolute; left:3px;top:5px'></div>
<div style='position:absolute; left:1px;top:3px'></div>
... and so on
But when I look at angular documentation it looks like I need to do:
<div ng-repeat="row in obj">
<div ng-repeat="col in row">
</div>
</div>
But this would created nested divs. Is there any way to create a flat div structure like I detailed above?
NOTE: Assume the data structure is as is (I can't create a flat list of objects)
^^^^^^
Upvotes: 2
Views: 678
Reputation: 4552
Short answer: as it is, no you can´t do it without nesting your divs
To do that you must modify your array, flattening it on your controller and then bind to the flattened array. Here is a working plunker: http://plnkr.co/edit/KPHurN2XBkvwMW22X3MP?p=preview
Your HTML should be like this:
<div ng-repeat="item in flattenedObj" style="left:{{item.x}} top: {{item.y}}">X: {{item.x}} | Y: {{item.y}}</div>
Note that you can apply this flattening on your controller, but the recommended way is to use a service for that, you are probably receiving this array from an endpoint via $http
, so treat it as you receive it.
UPDATE after reading that the structure should not be changed.
You can do this with directives, here is a working example:
http://plnkr.co/edit/Whf5YY8kV0zjEEM8vUAN?p=preview
app.directive('exampleDirective',[function(){
return{
restrict: 'E',
replace: true,
scope: {
sub: '='
},
template: '<div></div>',
link:function($scope, elem){
var resultingHtml = '';
for(var i=0; i<$scope.sub.length; i++){
resultingHtml += '<div style="top: '+ $scope.sub[i].y +'px; left: '+ $scope.sub[i].x +'px;">X:' + $scope.sub[i].x + ' Y:' + $scope.sub[i].y + ' </div>';
}
elem.replaceWith(resultingHtml);
}
}
}]);
If you try to make it using a ng-repeat
on the directive´s template, angular will try to use the upper scope because of the replace: true
, so you must do it the hard way.
Hope that helps
Upvotes: 1
Reputation: 25726
Since you cannot change the shape of your data, you must assume it has certain properties, such as each inner array always contains 3 objects.
<div ng-repeat-start="row in obj" style='position:absolute; left:{{row[0].x}}px;top:{{row[0].y}};'></div>
<div style='position:absolute; left:{{row[1].x}}px;top:{{row[1].y}};'></div>
<div ng-repeat-end style='position:absolute; left:{{row[2].x}}px;top:{{row[2].y}};'></div>
Upvotes: 0
Reputation: 3191
Yeah, you've got this ng-repeat which iterates through the javscript objects in your array. Access those object properties. so check this one-line out.
<div ng-repeat="row in obj" style="{{ 'position:absolute; left:' +row.x + 'px;top:' + row.y +'px;'}}"></div>
... or
<div ng-repeat="row in obj" style="position:absolute; left:{{row.x}}px;top:{{row.y}}px;"></div>
Upvotes: 0
Reputation: 7309
If you want a flat list, flatten it in the controller before binding to scope. Flattening out a list shouldn't happen in your view.
Upvotes: 0