繁体   English   中英

Angular 2+:使用主题(提供上下文)在孙指令(动态组件宿主)和SPECIFIC父组件之间进行通信

[英]Angular 2+: Communicate between grandchild directive (dynamic component host) and SPECIFIC parent component using Subjects (provide context)

我是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>

child-item.component.html

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

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

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

尝试通过@Output()从指令向组件发出事件失败后,我最终通过双向服务使用Subjects在发生单击时通过父母与孩子之间进行通信。

需求

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

问题

我可以将该布尔值传递给父级,但是我只需要对特定的父级项执行操作,该父级项刚刚注入了动态组件,因此在打开工具提示时该特定项不可拖动,但是其余的还是。 基本上,我需要一种为主题提供上下文的方法,以便可以识别从其各自的<child-item-component>中的哪个[contextMenuTrigger]指令触发了该事件,否则,所有项目组件都将接收该事件。并且它们都同时将[dragEnabled]为false,而没有机会区分它们。

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

  • 在主题上达到目标的最佳做法是什么?
  • 有没有一种方法可以使用作为参数发送给Subject的参数来检测事件的起源?
  • 我应该采取其他方法吗?

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

尝试记住使用click指令在child-item-component组件内被单击。

像这样:

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

这将始终带有新值,并且您的订阅将始终触发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM