在角材料中创建自定义选项卡

时间:2021-07-20 04:11:40

标签: angular typescript angular-material tabs

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

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

enter image description here

2 个答案:

答案 0 :(得分:0)

这只是“玩”[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 改变数组并将窗口滚动到顶部

  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 与更改

答案 1 :(得分:0)

还有另一种方法不使用 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 和一个 top 并创建一个动画来移动 nativeElement。另外我想最后传递另一个参数,如果参数为真,我可以在动画完成时执行一个动作

  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();
  }

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

  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