angular 如何根据屏幕另一个区域的某些条件从循环中呈现单个项目?

How to render single item from a loop based on some condition at a another area of a screen in angular?

谁知道如何渲染这种场景:

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

那么有没有什么方法可以在不同的地方渲染项目,通过某种 hack 或东西或功能,可以实现这种情况?

请指导我在 angular

中渲染这种场景的正确路径

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

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

依赖关系

  • Angular Material 组件 source

在您的 angular 项目根目录中添加 angular material 运行 ng add @angular/material。当提示添加动画时select是

修改你的模块:默认为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>

See demonstration on StackBlitz