3

I'm not exactly sure how to describe the issue I am having, or even if it is an issue. I guess I am having trouble wrapping my head around how Angular Directives work. Any advice and/or opinion on best practice is welcomed.

I have a simple array of objects in my controller's $scope:

$scope.birthdays = [
      { name: "bob", dob:moment("09/20/1953"), cake: "vanilla"},
      { name: "michael", dob:moment("09/20/1953"), cake: "chocolate" },
      { name: "dave", dob:moment("09/20/1953"), cake: "chocolate" },
      { name: "chief", dob:moment("04/24/1977"), cake: "chocolate" },
      { name: "jerry", dob:moment("04/24/1977"), cake: "red velvet" },
      { name: "jerkface", dob:moment("04/24/1977"), cake: "i hate cake" },
      { name: "doug", dob:moment("05/10/1994"), cake: "marble" },
      { name: "jeff", dob:moment("05/10/1994"), cake: "vanilla" }
];

Say I would like to create a DOM structure from this data model:

<h1>Birthday: 09/20/1953</h1>
<div class="birthday">
   <h2>Name: bob</h2>
   <h3>Cake: vanilla</h3>
</div>
<div class="birthday">
   <h2>Name: michael</h2>
   <h3>Cake: chocolate</h3>
</div>
<div class="birthday">
   <h2>Name: dave</h2>
   <h3>Cake: chocolate</h3>
</div>
<h1>Birthday: 04/24/1977</h1>
<div class="birthday">
   <h2>Name: chief</h2>
   <h3>Cake: chocolate</h3>
</div>
....

I can achieve something close to this in this plunker.

There, however, I end up with a slightly different DOM structure that I don't want.

<div ng-repeat="birthday in birthdays" birthday-boy="">
    <h3 ng-show="!birthdays[$index-1].dob.isSame(birthday.dob)" class="ng-binding" style="">
        September 20th, 1953
    </h3>
    <div class="ng-binding">
        Name: bob
    </div>
    <div class="ng-binding">
        Cake: vanilla
    </div>
</div>
<div ng-repeat="birthday in birthdays" birthday-boy="">
    <h3 ng-show="!birthdays[$index-1].dob.isSame(birthday.dob)" class="ng-binding" style="display: none;">
        September 20th, 1953
    </h3>
    <div class="ng-binding">
        Name: michael
    </div>
    <div class="ng-binding">
        Cake: chocolate
    </div>
</div>
<div ng-repeat="birthday in birthdays" birthday-boy="">
    <h3 ng-show="!birthdays[$index-1].dob.isSame(birthday.dob)" class="ng-binding" style="">
        April 24th, 1977
    </h3>
    <div class="ng-binding">
        Name: chief
    </div>
    <div class="ng-binding">
        Cake: chocolate
    </div>
</div>

So, my questions are:

  1. Am I thinking about this problem correctly? Should I be modifying my data structure to group it by dates there, and then just ng-repeat over each individual date?
  2. If there is a way to do this with my existing data structure, do I need to modify the DOM outside of the birthday-boy / ng-repeat directive?
  3. Is there a way to wrap the ng-repeat directive into something custom - I have started looking into the compile function but, just not sure...

Thanks!

Chief
  • 1,141
  • 9
  • 15
  • 1
    Comply to KISS principle and group it in controller (using $watch expression on `birthdays `). – Stewie Mar 18 '13 at 14:16
  • Thanks @stewie. Makes sense, for some reason I guess I thought it'd be better to implement a directive to take care of it. In the end that's probably faster/less expensive solution. – Chief Mar 18 '13 at 14:33

1 Answers1

2

I would group by dates in your controller, then ng-repeat over that new scope property. Here is a fiddle I wrote for a similar "group by" question. You should be able to adapt it for your code. I used the orderByFilter

$scope.sortedFriends = orderByFilter($scope.friends, '+age');

but you'll likely need to use the dateFilter or whatever JavaScript code you might have around to sort by the dob stuff.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • Thanks @Mark, I guess that makes sense as Stewie in the above comment to keep it simple, stupid. I suppose it will be less expensive to modify the data structure rather than have a group of logic inside my directive and have it modifying the DOM etc. – Chief Mar 18 '13 at 14:32
  • You end up with even "worse" DOM structure if you use something similar to the fiddle. And modifying data structure on every add/delete when there's 400 or so items can be pretty damn slow.. I'm having the same problem here http://stackoverflow.com/questions/15953236/angular-js-custom-iterations-data-transformations-and-grouping-when-simple-ng I can't believe it's such a pain in the arse to do something this simple.. – fxck Apr 12 '13 at 07:31