Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng-repeat to index into array

Tags:

angularjs

I have an angularjs app that streams data via ajax, and I would like to ng-repeat over the data. I have the data streaming and displaying but now I want to templatize the objects. The issue I am running into is that I am using ng-repeat simply to index into an array in the controller. I now need to have a

    <div class="row" data-ng-repeat="row in rows">
        <div class="span3" data-ng-repeat="col in cols">
            //displays the raw json fine
            {{ data[$parent.$index * numColumns + $index] }}                           
            // also displays the raw json
            {{ item = data[$parent.$index * numColumns + $index] }}                           
            <div>Id: {{item.Id}} </div>
            <div>Title: {{ item.ClientJobTitle }}</div>
            ...
        </div>
    </div>

I could always repeat the array index expression for each property, but there will be a couple dozen properties, so the code will be ugly and all the repeated calculations will slow things down.

What is the right (angular) way to do this?

Update I need it to be responsive too, I will be adjusting the number of columns on the fly based on window width.

Update I guess what I really want is something like the following non-working example

     <div class="row" data-ng-repeat="row in rows">
        <div class="span3" data-ng-repeat="col in cols">
            <div ng-model="data[$parent.$index * numColumns + $index]">
                <!-- Here $model would refer to the ng-model above -->
                <div>Id: {{$model.Id}} </div>
                <div>Title: {{ $model.Title }}</div>
                ...
            </div>
        </div>
    </div>
like image 758
µBio Avatar asked Apr 05 '13 15:04

µBio


1 Answers

You've probably handled the issue some way, but it's worth a mention that your non-working example is absolutely possible, even without directives:

var app = angular.module('app',[])
app.controller('myCtrl', function($scope) {
	$scope.numColumns = 2
	$scope.rows = [1,2,3]
	$scope.cols = [1,2]
	$scope.data = [
		{Id:'abc',Title:'cde'},
		{Id:'qwe',Title:'rty'},
		{Id:'asd',Title:'fgh'},
		{Id:'foo',Title:'bar'},
		{Id:'uni',Title:'corn'},
		{Id:'mag',Title:'ic'},
	];
	$scope.change1 = function(){
			$scope.numColumns = 2
		$scope.rows = [1,2,3]
		$scope.cols = [1,2]
	}
		$scope.change2 = function(){
			$scope.numColumns = 3
		$scope.rows = [1,2]
		$scope.cols = [1,2,3]
	}
});
.span3 {
	display:inline-block;
	padding:5px;
	margin:5px;
	background: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
<body ng-app="app">
	<div ng-controller="myCtrl">
		<button ng-click="change1()">2x3</button>
				<button ng-click="change2()">3x2</button>

	<div class="row" data-ng-repeat="row in rows">
        <div class="span3" data-ng-repeat="col in cols">
            <div>
							{{($model = data[$parent.$index * numColumns + $index])?'':''}}

                <!-- Here $model would refer to the ng-model above -->
                <div>Id: {{$model.Id}} </div>
                <div>Title: {{ $model.Title }}</div>
                ...
            </div>
        </div>
    </div>
	</div>
</body>

basically, it's possible to create such variable as "$model" on the fly, inside expression:

{{($model = data[$parent.$index * numColumns + $index])?'':''}}

It won't be printed itself, it'll be responsive, working inside ng-repeat and all. Still, it's kind of workaround, and directive might be a better choice.

like image 83
Michał Sałaciński Avatar answered Oct 10 '22 21:10

Michał Sałaciński