简体   繁体   中英

Use angularjs nested ng-repeat to construct complex table

I'm having trouble making proper table with nested ng-repeat.

What I wanted is this https://jsbin.com/razamagabo/1/edit?output

but I'm stuck at here https://plnkr.co/edit/d5voXIpzYL81sSl9BSY2?p=preview

I don't mind my markup is not table but I'm still stuck with div

<div class="row">
            <div class="col-xs-6" ng-repeat="obj in data">
                {{obj.date}}
                <div ng-repeat="user in obj.users">                 
                    <br>
                    {{user.name}}
                    <br>
                    {{user.mark}}
                </div>
            </div>
        </div>

In order for you to be able to display your data in the desired way, it will probably be easiest if you restructure your data in the JS before trying to render it.

It will be very complicated to try and match on the user names when they are in separate objects in the data array.

I would suggest processing your scope.data in the controller. (I'm assuming that you don't have much control on how you are receiving the data).

For example after you get your data...

$scope.data = [
    {
        date:'1-1-2016',
        users:[
            {
                'name':'james',
                'mark':18
            },
            {
                'name':'alice',
                'mark':20
            }
        ]
    },
    {
        date:'2-1-2016',
        users:[
            {
                'name':'james',
                'mark':60
            },
            {
                'name':'alice',
                'mark':55
            }
        ]
    }
]

var userData = {};
var possibleDates = [];
for (dataObj of Object.entries($scope.data)) {
    for (userObj of dataObj) {
        if ( !userData[userObj.name] ) {
            userData[userObj.name] = {};
        }
        userData[userObj.name][dataObj.date] = userObj.mark;
        if (dates.indexOf(dataObj.date) < 0) {
            dates.push(dataObj.date);
        }
    }
}

$scope.users = userData;
$scope.dates = possibleDates;

this will give you an object like this on your scope

$scope.users = {
    'james': {
        '1-1-2016': 18,
        '2-1-2016': 60
    },
    'alice': {
        '1-1-2016': 20,
        '2-1-2016': 55
    }
};

$scope.dates = ['1-1-2016', '2-1-2016'];

This to me seems easier to structure for your template. Though this assumes each user has an entry for each date.

<div>
    <div id='header-row'>
        <div id='empty-corner></div>
        <div class='date-header' ng-repeat='date in $scope.dates></div>
    </div>
    <div class='table-row' ng-repeat='{key, value} in $scope.users'>
        <div class='user-name'>{{ key }}</div>
        <div class='user-data' ng-repeat='date in $scope.dates>
            {{ value[date] }}
        </div>   
    </div>
</div>

As long as you apply inline-block styles to the rows/elements this should give you what you are looking for.

Though you can also think of ways to simplify your data even further. You could instead of having each user have an object where the dates are keys, you could just push the values into an array.

With your current data structure it is not possible to display it like you want. You are trying to loop over date-users objects in data array but then you want to display user from inside users array in separate rows. With ng-repeat you can loop through rows tr but not through columns. First you would need to map your data array to group elements that are supposed to be visible in 1 row into 1 object in array. Currently you have them in 2 separate objects: James mark: 18 and James mark: 60.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM