首页 > 解决方案 > 如何根据屏幕另一个区域的某些条件以角度从循环中渲染单个项目?

问题描述

任何人都知道如何呈现这种场景:

在此处输入图像描述

我知道可拖动库提供了禁用拖动的选项。但是,当项目被禁用拖动但另一个项目可以在拖动时更改不可拖动项目的位置时,这并不是更好的解决方案。

那么有没有办法在不同的地方渲染项目某种黑客或东西或功能,通过这种方式可以完成这种场景?

请指导我在正确的道路上以角度呈现这种场景

标签: angularrenderngforangular-cdk

解决方案


将支持数组拆分为两个可观察对象

由于我们关注一个源但需要在两个不同的位置输出项目的子集,我们将采用一种方法来保留一个内部 BehaviorSubject,我们可以从中派生多个 observables,以创建我们过滤的子集。

依赖关系

  • Angular 材质组件

ng add @angular/material在您的角度项目根目录中添加角度材料运行。当提示添加动画时,选择是

修改你的模块:默认是 app.module

在您可以使用 CDK 拖放指令之前,您必须将DragDropModule添加到您的导入中。

@NgModule({
  declarations: [
   ...
  ],
  imports: [
    ...
    DragDropModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

创建组件

控制器


@Component({
  selector: 'drag-drop-demo',
  templateUrl: './drag-drop-demo.component.html',
  styleUrls: ['./drag-drop-demo.component.scss']
})

export class DragDropDemoComponent implements OnInit, OnChanges, OnDestroy {
  // utilize behaviorSubject so we always get the latest input in our observables regardless of lifecycle timing.
  private internal!: BehaviorSubject<number[]>;
  @Input() listItems!: number[];
  conditionAppliesList!: number[];
  conditionDoesNotApplyList!: number[];
  subscriptions: Subscription;


  constructor() {
    this.internal = new BehaviorSubject<number[]>([]);
    this.subscriptions = new Subscription();
  }

  ngOnInit(): void {
    // setup two distinct observables that apply some filter condition to our list.
    this.subscriptions.add(
      this.internal.asObservable()
        .pipe(map(items => items.filter(number => number % 2 == 0))).subscribe(numbers => {
        this.conditionAppliesList = numbers;
      })
    );
    this.subscriptions.add(
      this.internal.asObservable()
        .pipe(map(items => items.filter(number => number % 2 != 0))).subscribe(numbers => {
        this.conditionDoesNotApplyList = numbers;
      })
    );
  }

  ngOnChanges(changes: SimpleChanges): void {
    // when listItems are detected in our input, emit the values in the internal BehaviorSubject
    if ('listItems' in changes) {
      // emit next value
      this.internal.next(this.listItems);
    }
  }

  ngOnDestroy() {
    // cleanup the subscriptions.
    this.subscriptions.unsubscribe();
  }

  // cdkHandler.
  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.conditionAppliesList, event.previousIndex, event.currentIndex);
  }
}

模板

<h2>Drag and drop</h2>
<div class="list-outlet">
  <h3>Draggable</h3>
  <div class="list-container" cdkDropList (cdkDropListDropped)="drop($event)">
    <div class="list-item" *ngFor="let num of conditionAppliesList" cdkDrag>
      {{num}}
    </div>
  </div>
  <h3>Non-Draggable</h3>
  <div class="list-container">
    <div class="list-item" *ngFor="let num of conditionDoesNotApplyList">
      {{num}}
    </div>
  </div>
</div>

查看 StackBlitz 上的演示


推荐阅读