【问题标题】:Angular 2+: Communicate between grandchild directive (dynamic component host) and SPECIFIC parent component using Subjects (provide context)Angular 2+:使用主题(提供上下文)在孙指令(动态组件宿主)和特定父组件之间进行通信
【发布时间】:2018-11-14 09:37:53
【问题描述】:

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

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

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

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

要求

我需要将&lt;child-item-component&gt; 上的[dragEnabled] 设置为false。

问题

我能够将该布尔值传递给父项,但我只需要对特定父项采取操作,即刚刚注入动态组件的项,以便在工具提示时该特定项不可拖动是开放的,但其余的仍然是。 基本上,我需要一种为主题提供上下文的方法,以便我可以从它们各自的&lt;child-item-component&gt; 中的哪个[contextMenuTrigger] 指令中识别出触发了事件,否则,所有项目组件都接收到事件并且所有它们同时将[dragEnabled]转为false,没有任何区分的机会。

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

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

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

【问题讨论】:

    标签: angular


    【解决方案1】:

    尝试使用 click-directive 记住在 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());
    

    这总是会产生一个新值,并且你的订阅总是会触发。

    【讨论】:

      猜你喜欢
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多