Angular指令简化排序

时间:2018-01-29 13:38:51

标签: angular angular2-directives angular-directive

我有一个列表/人员表,我可以按名字,姓氏等排序。

当我点击标题(比如名字)时,它会使用查询字符串参数进行路由 ?sort=firstname,如果我再次点击它,它会将参数更改为 ?sort=firstname-desc。同时,我需要一个图标来显示参数旁边的向上或向下箭头,指示升序或降序排序。这是一个非常标准的排序方案。

我目前的模板如下所示:

<div class="heading">
    First name
    <a [routerLink] [queryParams]="sortParams('firstname')">
        <img src="assets/icons/icon-sort-down.svg" class="icon-normal" [class.flip]="showFlip('firstname')">
    </a>
</div>

这很好用,因为我在组件中有一些逻辑来处理sortParamsshowFlip但我想简化它,所以我可以轻松地将相同的逻辑添加到多个字段,并且多个视图,无需额外的重复组件逻辑。

创建指令似乎是要走的路,但是当我创建指令时,我通常只使用@HostBinding修改dom属性。怎么可能写一个指令(称之为排序),这将允许我这样定义模板:

<div class="heading">
    First name
    <a [sorting]="'firstname'"></a>
</div>

该指令需要修改a标记以包含routerLinkqueryParams,以及添加一些非静态模板内容。我知道我可以在我的指令中注入ViewContainerRef,但从那里,我的指导性知识需要一些帮助。

2 个答案:

答案 0 :(得分:1)

请试试这个:

import {Directive, Input} from '@angular/core';
import {YourSortingService} from 'YouServiceFileLocation';


@Directive({
  selector:'[sorting]'
})
export SortingDirective{
   @Input() sortingQueryString:string;

   constructor(private sortingService:YourSortingService){}


   @HostBinding('click')
   private onClick(){
     //On click on the <a> tag
     this.sortingService.get(`url?sort=${this.sortingQueryString}`);
   }
}

你可以像这样使用它:

<div class="heading">
     First name
     <a sorting [sortingQueryString]="'firstname'"></a>
</div>

答案 1 :(得分:1)

好的,所以我想出写一个指令来解决这个问题是一个坏主意。我真正需要的只是一个包装逻辑的组件。

我最终得到了我想要的标记/模板。实际上,我可能会像我设置的那样令人兴奋,但决定反对执行路由器解析的组件,而是将查询字符串排序参数解析为组件,以便对其进行最终处理。

<div class="heading">
    First name
    <fd-sorting-header [fieldName]="'firstname'" [sort]="sort"></fd-sorting-header>
</div>

所以我创建了一个组件来解析排序查询字符串和设置routerLink / queryParams。组件模板最终如下:

<a [routerLink] [queryParams]="sortParams"><img src="assets/icons/icon-sort-down.svg" class="icon-normal" [class.flip]="showFlip"></a>

这样一个简单的类:

export class SortingHeaderComponent {
  public sortParams: any;
  public showFlip: boolean;

  @Input('fieldName') fieldName: string;
  @Input('sort')
  set sort(sort: string) {
    const [column, dir] = (sort || '').split('-');
    const direction = (dir && dir.toLowerCase() === 'desc') ? 'desc' : 'asc';

    this.showFlip = column === this.fieldName && direction !== 'desc';
    this.sortParams = { sort: this.fieldName + ((this.showFlip) ? '-desc' : '') };
  }

  constructor() { }
}