Pol M Pol M - 1 month ago 15
AngularJS Question

Angular.js ng-repeat notation

I' have a bunch of objects with an array I want to iterate over. Works as expected *image

{

"name": "X-Wing",
"factions": "rebels",
"attack": 3,
"agility": 2,

"dial": [ // This is the data I want
[0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 0, 0],
[1, 1, 2, 1, 1, 0],
[1, 1, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 3]
]
}, // n...



// Jade
.dials(ng-repeat="dial in dials track by $index")
div(ng-repeat="moves in dial track by $index")
span(ng-repeat="move in moves track by $index ",
ng-class="{'empty': move === 0, 'white': move === 1,
'green': move === 2, 'red':move === 3}") {{move}}


Thing is I'm looking for a more complex visualization (* image) but all I came up with is a code that works but looks ugly and smells funny. My question, is there a better way of doing this writing less code ?

.dials(ng-repeat="dial in dials track by $index")

div.row-dial
span(ng-class="{ 'white': dial[0][0] === 1,'green': dial[0][0] === 2, 'red':dial[0][0] === 3}")
i(ng-if="dial[0][0] === 0") X
i.xwing-miniatures-font.xwing-miniatures-font-turnleft(ng-if="dial[0][0] > 0")

span(ng-class="{ 'white': dial[0][1] === 1,'green': dial[0][1] === 2, 'red':dial[0][1] === 3}")
i(ng-if="dial[0][1] === 0") X
i.xwing-miniatures-font.xwing-miniatures-font-bankleft(ng-if="dial[0][1] > 0")

span(ng-class="{ 'white': dial[0][2] === 1,'green': dial[0][2] === 2, 'red':dial[0][2] === 3}")
i(ng-if="dial[0][2] === 0") X
i.xwing-miniatures-font.xwing-miniatures-font-straight(ng-if="dial[0][2] > 0")
span(ng-class="{ 'white': dial[0][3] === 1,'green': dial[0][3] === 2, 'red':dial[0][3] === 3}")
i(ng-if="dial[0][3] === 0") X
i.xwing-miniatures-font.xwing-miniatures-font-bankright(ng-if="dial[0][3] > 0")
span(ng-class="{ 'white': dial[0][4] === 1,'green': dial[0][4] === 2, 'red':dial[0][4] === 3}")
i(ng-if="dial[0][4] === 0") X
i.xwing-miniatures-font.xwing-miniatures-font-turnright(ng-if="dial[0][4] > 0")
span(ng-class="{ 'white': dial[0][5] === 1,'green': dial[0][5] === 2, 'red':dial[0][5] === 3}")
i(ng-if="dial[0][5] === 0") X
i.xwing-miniatures-font.xwing-miniatures-font-kturn(ng-if="dial[0][5] > 0")


div.row-dial

span(ng-class="{ 'white': dial[1][0] === 1,'green': dial[1][0] === 2, 'red':dial[1][0] === 3}")
i(ng-if="dial[1][0] === 0") X

i.xwing-miniatures-font.xwing-miniatures-font-turnleft(ng-if="dial[1][0] > 0")
span(ng-class="{ 'white': dial[1][1] === 1,'green': dial[1][1] === 2, 'red':dial[1][1] === 3}")
i(ng-if="dial[1][1] === 0") X

i.xwing-miniatures-font.xwing-miniatures-font-bankleft(ng-if="dial[1][1] > 0")
span(ng-class="{ 'white': dial[1][2] === 1,'green': dial[1][2] === 2, 'red':dial[1][2] === 3}")
i(ng-if="dial[1][2] === 0") X

i.xwing-miniatures-font.xwing-miniatures-font-straight(ng-if="dial[1][2] > 0")
span(ng-class="{ 'white': dial[1][3] === 1,'green': dial[1][3] === 2, 'red':dial[1][3] === 3}")
i(ng-if="dial[1][3] === 0") X

i.xwing-miniatures-font.xwing-miniatures-font-bankright(ng-if="dial[1][3] > 0")
span(ng-class="{ 'white': dial[1][4] === 1,'green': dial[1][4] === 2, 'red':dial[1][4] === 3}")
i(ng-if="dial[1][4] === 0") X

i.xwing-miniatures-font.xwing-miniatures-font-turnright(ng-if="dial[1][4] > 0")
span(ng-class="{ 'white': dial[1][5] === 1,'green': dial[1][5] === 2, 'red':dial[1][5] === 3}")
i(ng-if="dial[1][5] === 0") X

i.xwing-miniatures-font.xwing-miniatures-font-kturn(ng-if="dial[1][5] > 0")


// ... you get the idea...

Answer

You can simplify it by choosing the class based on $index. Something like (indentation may need to be changed, I tried to follow the original indentation):

.dials(ng-repeat="dial in dials track by $index")
div.row-dial(ng-repeat="moves in dial track by $index")
span(ng-repeat="move in moves track by $index ", ng-class="{'white': move === 1, 'green': move === 2, 'red':move === 3}")
  i(ng-if="move === 0") X
  i.xwing-miniatures-font(ng-if="move > 0", ng-class="{
    'xwing-miniatures-font-turnleft': $index === 0,
    'xwing-miniatures-font-bankleft': $index === 1,
    'xwing-miniatures-font-straight': $index === 2,
    'xwing-miniatures-font-bankright': $index === 3,
    'xwing-miniatures-font-turnright': $index === 4,
    'xwing-miniatures-font-kturn': $index === 5}")

However, this is not very concise, so I would use a lookup table for both classes:

$scope.fontColors = [null, 'white', 'green', 'red'];
$scope.fontClasses = ['xwing-miniatures-font-turnleft', 'xwing-miniatures-font-bankleft', 'xwing-miniatures-font-straight', 'xwing-miniatures-font-bankright','xwing-miniatures-font-turnright', 'xwing-miniatures-font-kturn'];

Then the template can be (indentation may need to be changed):

.dials(ng-repeat="dial in dials track by $index")
div.row-dial(ng-repeat="moves in dial track by $index")
span(ng-repeat="move in moves track by $index ", ng-class="fontColors[move]")
  i(ng-if="move === 0") X
  i.xwing-miniatures-font(ng-if="move > 0", ng-class="fontClasses[$index]")