在 angular material 中创建自定义标签

creating custom tabs in angular material

我们如何实施或知道如何创建自定义选项卡,例如在下面的示例图片上?例如 general , security role 和 sso 以及 password 和 login 都是选项卡。如果我单击常规选项卡,它会在右侧显示常规卡,如果我单击安全角色和 sso,它将显示安全角色和 sso 卡,就像它会在顶部滚动一样,它会在一般位置上卡片。对这些家伙有什么想法吗?谢谢。

https://stackblitz.com/edit/angular-mat-card-example-flsnue

只是和[fxFlexOrder]

“玩”

如果你定义了一个像

这样的数组
order=[0,1,2]

每个 fxFlex 都可以像

//use order[0] and sortOrder(0) for the first div
//    order[1] and sortOrder(1) for the second one
//    ...
<div fxFlex [fxFlexOrder]="order[0]" (click)="sortOrder(0)">
..
</div>

函数 sortOrder 更改数组并将 window 滚动到顶部

  sortOrder(index) {
    const value=this.order[index]
    if (value != 0) {
      this.order = this.order.map(
        (x, i) => (x = i == index ? 0 : x < value ? x + 1 : x)
      );
      window.scrollTo(0, 0);
    }
  }

你的 forked stackblitz 有变化

还有另一种方法不使用 mat-flex else div 位置绝对和手动动画。

想象一个html喜欢

<div class="container">
    <div class="column">
        <mat-card class="custom">
            {{order|json}}
        </mat-card>
    </div>
    <div class="column">
        <div #card (click)="sortOrder(0)">
            <mat-card class="custom2">
                custom 0
            </mat-card>
        </div>
        <div #card (click)="sortOrder(1)">
            <mat-card class="custom2">
                custom 1
            </mat-card>
        </div>
        <div #card (click)="sortOrder(2)">
            <mat-card class="custom2">
                custom 2
            </mat-card>
        </div>
    </div>
</div>

有一个.css喜欢

.container{
  display:flex;
}
.column{
  margin-left:15px;
}
.column>div
{
  position:absolute;
}

想法是创建一个手动动画。为此,我们使用 @ViewChildren “卡片”并注入构造函数 AnimationBuilder

  timing = '500ms ease-in-out';
  initPos=0;
  @ViewChildren('card', { read: ElementRef }) items: QueryList<ElementRef>;
  private player: AnimationPlayer;
  constructor(private builder: AnimationBuilder) {}

我们的函数“animate”接收到一个 nativeElement 和一个顶部,并创建一个动画来移动 nativeElement。另外我想最后传递另一个参数,如果参数为 true

,则允许​​我在动画结束时执行一个动作
  animate(element: any, top: string | number,last:boolean) {
    const myAnimation = this.builder.build([
      animate(this.timing, style({ top: top}))
    ]);
    this.player = myAnimation.create(element);
    if (last)
    {
      this.player.onDone(()=>{
        window.scrollTo(0, 0);
      })
    }
    this.player.play();
  }

所以唯一的就是根据我们在点击时更改的数组顺序计算位置“顶部”

  sortOrder(index: number) {
    const value = this.order[index];
    if (value != 0) {
      this.order = this.order.map(
        (x, i) => (x = i == index ? 0 : x < value ? x + 1 : x)
      );
      
    }
    let pos = this.initPos ||0;
    for (let i=0;i<this.order.length;i++)
    {
      const index=this.order.findIndex(x=>x==i);
      const card = this.items.find((_, j) => j == index);
      if (card) {
        this.animate(card.nativeElement, pos ? pos + 'px' : 0,i==this.order.length-1);
        pos += card.nativeElement.getBoundingClientRect().height;
      }

    }
  }

最后,别忘了在ngAfterViewInit中调用函数sortOrder

  ngAfterViewInit()
  {
    this.initPos=this.items.first.nativeElement.getBoundingClientRect().top;
    this.sortOrder(0)
  }

stackblitz