-2

I like to use ng-repeat to print data to my html using Angularjs, i have to use unique and orderBy to avoid equals in year and month.

My data:

demo.data = 
  [
      { "year": 2016, "month": "November", "item": "November 01"}
    , { "year": 2016, "month": "November", "item": "November 02"}
    , { "year": 2016, "month": "January", "item": "January 01"}
    , { "year": 2015, "month": "December", "item": "December 01"}
  ];

Structure:

<ul>
  <li>
    <span>Year</span>
    <ul>
      <li>
        <span>Month</span>
        <ul>
          <li>
            <span>Item</span>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Example: http://plnkr.co/edit/Ddc5PIYZAduOdzihnNO7?p=preview

  • I tried use ng-repeat, but `month` not is a array inside year.. This cause a problem with ng-repeat. – user3251174 Feb 23 '17 at 01:20
  • show us the code please – Satya Feb 23 '17 at 01:20
  • you should structure your data in your controller so that it matches what you want to display. don't expect angular to know how to separate your data for you, and don't try to modify the data in the view. – Claies Feb 23 '17 at 01:21
  • `ng-repeat` must use for `array`, you just have an array is `data`, `year`, `month`, `item` are not array, you can't use `ng-repeat` for it. – Huy Chau Feb 23 '17 at 01:22
  • @WorkMe, i know that, because that i liked to use only ng-repeat and not have a loop to create another object/array – user3251174 Feb 23 '17 at 01:29
  • you don't have nested data here, you have flat data. you can't expect angular to turn your flat data into a nested display. – Claies Feb 23 '17 at 01:30
  • @Satya, @Claies; I add the example with my try. – user3251174 Feb 23 '17 at 01:30
  • Possible duplicate of [AngularJs Remove duplicate elements in ng-repeat](http://stackoverflow.com/questions/20222555/angularjs-remove-duplicate-elements-in-ng-repeat) – Naguib Ihab Feb 23 '17 at 01:38
  • @Claies, my idea is not create another array. I see this project https://github.com/a8m/angular-filter/, but i dont know if its help. – user3251174 Feb 23 '17 at 01:39
  • This is not what the view is for. If you don't want to structure the data correctly for the display you want, then this isn't the framework you should be using. Don't make your users suffer because you don't want to organize your data properly. Even if you manage to get this working with some sort of nested `ng-repeat` or series of filters, you are only **purposely** creating a performance issue for your app, unnecessarily. – Claies Feb 23 '17 at 01:40
  • @Claies, The number of iterations creating another array is bigger. Because i have to use ng-repeat creating or not another array. – user3251174 Feb 23 '17 at 01:48
  • no, it really isn't. By trying to do it this way, you are asking angular to iterate through the array 3 times, and expecting it to filter out the things that you don't want to see on each loop. and then, every time the data changes, **all** of the `ng-repeat` loops will be re-evaluated. This is a performance nightmare, and a troubleshooting nightmare as well. But good luck to you if you manage to find a way to make this work; I can't make you do it the proper way. – Claies Feb 23 '17 at 01:51
  • I created a plunker that shows re-organizing the data in the controller, just in case you are interested; I'm relatively positive this gives the output you are expecting: http://plnkr.co/edit/c7XpXzTE0HeCgqRs2xpH?p=preview. It uses the `(key, value)` syntax of `ng-repeat`, but demonstrates that the `key` and `value` names can be changed. – Claies Feb 23 '17 at 02:12
  • I created another fork with @codepills answer side by side with the code I wrote: http://plnkr.co/edit/k6AKZh29r9xCuLobHtcH?p=preview. I encourage you to compare the difference in the HTML output between the two, and take note of the multitude of commented out rows in the `ng-if` example. – Claies Feb 23 '17 at 02:17

2 Answers2

2

The nested items should only be included if they are in the same associated year and/or month. Adding ng-if conditions may be what you are looking for.

<body ng-controller="DemoController as demo">
  <ul>
    <li ng-repeat="y in demo.data | orderBy:'+year' | unique:'year'">
      <span ng-bind="y.year"></span>
      <ul>
        <li ng-repeat="m in demo.data | orderBy:'+month' | unique:'month'" ng-if="m.year == y.year">
          <span ng-bind="m.month"></span>
          <ul>
            <li ng-repeat="i in demo.data | orderBy:'+item' | unique:'item'" ng-if="i.year == y.year && i.month == m.month">
              <span ng-bind="i.item"></span>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</body>
callmepills
  • 672
  • 9
  • 13
0

The example code you've provided doesn't really make a lot of sense. Firstly the data wont be available on your page because you haven't added it to the scope. demo.data should look similar to $scope.data

ng-repeat is added to an element of your html. You can also add some 'keywords' such as orderBy and 'unique' to manipulate how the output is handled by angular.

Every element nested inside our repeating <li> will be repeated for each json object in data. This data will have it's year, month and item value written to the page where the {{}} enclosed values are. For instance {{date.year}} will display the date's year.

The orderBy: 'year' will arrange the dates by the year, and the unique: 'item' will ensure only one object with the item value is provided.

<ul>
  <li ng-repeat="date in data | unique:'item' | orderBy: 'year'">
    <span>{{date.year}}</span>
    <ul>
      <li>
        <span>{{date.month}}</span>
        <ul>
          <li>
            <span>{{date.item}}</span>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

You need to do a little more research before asking a question. You've essentially just asked somebody to write you code for you. Even if you were to copy what I, or anyone else, gave you I don't think you yet have the understanding of angular to actually implement it. Please spend some more time learning angular and you'll find it's actually quite easy!

Here are some resources regarding ng-repeat to check out;

https://docs.angularjs.org/api/ng/directive/ngRepeat

https://www.w3schools.com/angular/ng_ng-repeat.asp

EDIT: You plunker example is very different from the kind of result I thought you were after.

  • this isn't going to produce the result the OP is expecting either, but that's mostly because the data isn't structured properly to be displayed in the manner expected. `ng-repeat` can't make flat data into nested data. – Claies Feb 23 '17 at 01:37
  • Your code generate duplicates to year and month. About the data scope, i dont have use $scope, i recommend to read: https://toddmotto.com/a-better-way-to-scope-angular-extend-no-more-vm-this/ – user3251174 Feb 23 '17 at 01:37
  • If you want a list of years, with months, then dates, you will need to create a data structure that consists of nested arrays. Then you will be able to nested ng-repeats on each of the levels you're after. –  Feb 23 '17 at 01:42