2017-08-25 72 views
1

我无法使用列表分隔符在中间项目类别之间创建列表。 分隔符应该标题为月份名称,并且该项目应该有该月份发布的项目。在Angular 4中使用列表分隔符列表

我想要实现:

- August 
    - list item 1 
    - list item 2 
- September 
    - list item 3 
    - list item 4 
    - list item 5 

每个列表项具有日期戳在那里我从一个月中提取。

我已经试过

export class PostItemService { 
    groupedItems = []; 

    // second item is the date timestamp 
    items: item[] = [ 
    new item('cool title', 1503469292, 'some cool text'), 
    new item('second title', 1503469292, 'some cool text'), 
    new item('third title', 1503469292, 'some cool text'), 
    ]; 

    splitOnMonth() { 

    const items = this.items; 
    const groupedItem = []; 

    // extract the month number 
    function convertTimeStamp(timestamp) { 
     const date = new Date(timestamp * 1000); 
     const monthNumber = date.getMonth() + 1; 

     return monthNumber; 
    } 

    items.forEach((value, index) => { 

     const myMonth = convertTimeStamp(value.date); 

     // Actually, I don't now where to go from here 

    }); 

    } // splitOnMonth() 

} 

我已经尝试了很多东西,但我不认为有必要在这里添加。主要的是;我不知道该从哪里出发。

我希望有人遇到并解决了同样的问题,或可以帮助我。

预先感谢您。

+0

我在代码中并没有真正看到你试图描述你所描述的内容吗?你刚刚宣布了一个数组,并且你有一些解析月份的逻辑...... – diopside

+0

我已经做了多次尝试,但我只是不断地把它们都记下来,因为它们不起作用。我已经尝试使用.map()方法,我尝试添加一个临时数组并填充该数组。我可以在这个代码块中添加所有这些尝试,但我认为它会超出这个问题。 虽然我仍然可以提供它们。 –

回答

1

我只是创建一个由月份编号标识的月份对象地图,每个对象中包含2个属性,名称和包含该月份所有项目的数组。遍历所有项目以查找他们的月份,然后将它们推入相应月份的空数组(如果该对象尚不存在,则创建对象),然后在模板中迭代月数组并仅显示项目1个或多个子项目,如果他们有子项目,则遍历该数组。

更新 - Plunkr链接 - https://plnkr.co/edit/w6EaEe9yoVMr7OKExXwc?p=preview

export class PostItemService { 

    monthMap : { [index : number] : { monthName: string, items: item[] }}; 
    monthArray: any[] = []; 

    items: item[] = [ 
     new item('cool title', 1503469292, 'some cool text'), 
     new item('second title', 1503469292, 'some cool text'), 
     new item('third title', 1503469292, 'some cool text'), 
    ]; 

    constructor() { 
     this.monthMap = { 
      1: { monthName: 'January', items: [] }, 
      2: { monthName: 'February', items: [] }, 
      3: { monthName: 'March', items: [] }, 
       // ... and so on ... dont want to type it all 
       // you could build this iteratively if you just had a 12 length array of the string names, but its easier to show it explicitly for the example 
       // ideally you could just create an empty map and only add a month object if it ends up with items, that would prevent you from having to check lengths later. 
     }; 

     this.splitOnMonth(); 
    } 

    splitOnMonth() { 

    // extract the month number 
    var convertTimeStamp = (timestamp)=> { 
     const date = new Date(timestamp * 1000); 
     const monthNumber = date.getMonth() + 1; 
     return monthNumber; 
    } 

    items.forEach((value, index)=>{ 

      const myMonth = convertTimeStamp(value.date); 

      this.monthMap[myMonth].items.push(value); 
    }); 

    // after that method completes, you can convert your month map to an array, only adding the numbered objects to the array if they have items in their items array 

    for (let prop in monthMap) { 
     if (this.monthMap[prop].items.length > 0) { 
      this.monthArray.push(this.monthMap[prop]); 
     } 
    } 

    // now you have an array you can iterate through in the template of a component somewhere 
    } 

} 

在某些组件的模板......

<ul class="month-groups"> 
    <li *ngFor="let month of this.monthArray"> 
     {{ month.monthName }} 
     <ul class="month-items"> 
      <li *ngFor="let item of month.items"> 
       {{ item.value }} // or whatever info from items you need to show 
      </li> 
     </ul> 
    </li> 
</ul> 

应该这样做,你只可能要适当的样式不同的UL的,并可能会为嵌套元素添加额外的余量。

注 - 您在forEach函数中缺少一个胖箭头。另外 - 在角度上,你通常希望避免在组件的构造函数中做很多事情,但对于服务来说它很好,因为它们没有相关的视图来渲染。我在构造函数中实例化月份映射,以便将它与上面的类型化声明分开,并使其更清晰。如果这是一个服务,你可能不会从构造函数调用splitMonth()方法,但是如果你只是想测试它,这是一个简单的方法。

+0

太棒了。非常感谢你。好的解决方案 –

+0

另外我真的不明白日期时间戳,所以我只是随机更改了它们的数字以获得月份改变... – diopside

+0

显然我不知道如何分享链接链接...这是否适合你? https://plnkr.co/edit/w6EaEe9yoVMr7OKExXwc?p=preview – diopside

0

您应该考虑为此创建一个管道。

看看这个片断:

@Pipe({ 
     name: 'ItemsFilterPipe', 
     pure: false 
    }) 
    export class ItemsFilterPipe implements PipeTransform { 
     transform(items: Item[]): FilteredItem[] { 
     // Here you can do whatever you want with your data like creating a new object with timestamp as key and the item as value 
     } 
    } 

,你可以用它如下:

*ngFor="let item of items | ItemsFilterPipe" 
在这个ngFor

,项目包含{ “1503469292”:项目[]}

+1

OP - 这可能是一个更好,更干净的解决方案,如果您只需要显示这样的数据,并且您实际上不需要按月组织它 – diopside