Angular 2+:使用Subjects(提供上下文)

时间:2018-06-05 01:50:36

标签: angular

我是Angular 2+的新手,我面临一个微不足道的局面,我似乎没有找到出路。

我有一个父组件(parent.component.html),它包含通过迭代呈现的组件列表(item.component.html),如下所示:

parent.component.html

<child-item-component *ngFor="let date of shift?.dates" [shift]="shift"
    [dragEnabled]="dragEnabled"></child-item-component>

子-item.component.html

<li [contextMenuTrigger]="contextMenuData">
  <ng-template contextMenuHost></ng-template>
</li>

每个子组件都有一个<li>元素,并附有[contextMenuTrigger]指令。该指令包含注入动态组件的逻辑,这是一个具有不同操作的工具提示,与此无关。

当用户点击持有指令(<li>)的元素时,将呈现动态组件。

尝试通过@Output()从指令向组件发出事件但没有成功后,我最终通过双向服务使用Subjects在发生点击时在父母和孩子之间进行通信。

需要量

我需要将[dragEnabled]上的<child-item-component>设置为false。

问题

我能够将该布尔值传递给父级,但是我需要对特定的父级项目执行操作,该项目刚刚注入了动态组件,因此在工具提示时此特定项目不可拖动是开放的,但其余的仍然是。 基本上,我需要一种方法来为Subject提供上下文,以便我可以识别其各自[contextMenuTrigger]内的<child-item-component>指令触发事件,否则,所有项目组件都会收到事件并且所有这些都同时将[dragEnabled]变为假,而没有任何机会区分它们。

我一直在四处寻找,我看不到有人在这里遇到同样的情况,所以我想知道我做错了什么。

  • 在主题上实现这一目标的最佳做法是什么?
  • 有没有办法通过使用参数来检测事件的起源 作为参数发送给主题?
  • 我应该采取不同的方法吗?

希望我足够清楚。提前谢谢大家。

1 个答案:

答案 0 :(得分:0)

尝试使用click-directive来记住在子项目组件中单击。

这样的事情:

<强> TS-文件

// I guess this is something similar to your Subject-Solution
@Input() dragEnabled: Subject<boolean> = new Subject();

// your memory of being clicked
private isClicked: boolean = false;

...

constructor(){
    this.dragEnabled.subscribe( () => {
       this.onDragEnabledEvent();
    });
}

private clicked(): void {
   this.isClicked = true;
}

...

// this method is triggered by your Subject out of the subscription
// only the clicked element is blocked all the others get unblocked
onDragEnabledEvent(): void {
    if(this.isClicked) {
        this.isClicked = false; // reset

        // YOUR BLOCKING CODE GOES HERE

    } else

        // YOUR UNBLOCKING CODE GOES HERE

    }
}

<强> HTML-模板

<child-item-component *ngFor="let date of shift?.dates" [shift]="shift"
[dragEnabled]="dragEnabled" (click)="clicked()"></child-item-component>

<强> dragEnabled

请注意,如果内容发生更改,“主题”仅会触发新事件。由于内容本身对您不感兴趣,我建议如下:

将当前日期作为UTC时间戳字符串发送

subject.next(new Date().getTime());

这将始终提供一个新值,并且您的订阅始终会触发。