【问题标题】:Angular 6 using ContentChildren/ViewChildren in AngularElements - CustomComponentsAngular 6 在 AngularElements - CustomComponents 中使用 ContentChildren/ViewChildren
【发布时间】:2018-05-27 17:54:41
【问题描述】:

我正在尝试新的 AngularElements 功能。 (https://angular.io/guide/elements)

第一次测试是成功的,但是一旦我集成了@ContentChildren,它就会停止工作。这对我来说似乎是合乎逻辑的,因为作为 CustomElement 的新创建的组件无法通过 Angular-Context 获取引用,因为它位于应用程序之外。

我的目标是制作一个最小的 Tab-Wrapper / Tab - 类似于 angular.io 中使用的组件结构

<custom-tab-wrapper>
  <anb-tab [title]="'Test'">
    Content
  </anb-tab>
</custom-tab-wrapper>

我还创建了一个 Stackblitz,但这似乎更糟,因为 HMR 多次定义组件,这会导致错误。但这应该让您更好地了解我想要实现的目标。

https://stackblitz.com/edit/angular-byvpdz?file=src%2Fapp%2Ftab-wrapper%2Ftab-wrapper.component.ts

这里是主要文件:

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularBlog</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<anb-root></anb-root>
<custom-tab-wrapper>
  <anb-tab [title]="'Test'">
    Content
  </anb-tab>
</custom-tab-wrapper>
</body>
</html>

tab-wrapper.component.ts

import {AfterContentInit, Component, ContentChildren, OnInit, QueryList, ViewEncapsulation} from '@angular/core';
import {TabComponent} from '../tab/tab.component';

   import {AfterContentInit, Component, ContentChildren, OnInit, QueryList, ViewEncapsulation} from '@angular/core';
import {TabComponent} from '../tab/tab.component';

@Component({
  selector: 'anb-tab-wrapper',
  template: `
    <div class="tab-selection-wrapper">
      <h1>Test</h1>
      <div class="tab-selection" (click)="enableTab(tab)" *ngFor="let tab of tabs.toArray()">
        {{tab.title}}
      </div>
    </div>
    <div class="tab-content">
      <ng-content></ng-content>
    </div>
  `,
  encapsulation: ViewEncapsulation.Native
})
export class TabWrapperComponent implements OnInit, AfterContentInit {
  @ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

  constructor() {
    setInterval(() => {
      console.log(this.tabs);
    }, 2000);
  }

  public enableTab(tab: TabComponent) {
    tab.active = true;
    this.tabs.toArray().forEach(tabToCheck => {
      if (tab !== tabToCheck) {
        tabToCheck.active = false;
      }
    });
  }

  ngAfterContentInit(): void {
  }


  ngOnInit() {
  }

}

然后我会有一个选项卡组件。如果我在 angular-root-element 中使用它而不是作为 WebComponent 使用它,它会正确呈现。

app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {Injector, NgModule} from '@angular/core';

import {AppComponent} from './app.component';
import {TabWrapperComponent} from './tab-wrapper/tab-wrapper.component';
import {TabComponent} from './tab/tab.component';
import {createCustomElement} from '@angular/elements';

@NgModule({
  declarations: [
    AppComponent,
    TabWrapperComponent,
    TabComponent
  ],
  entryComponents: [
    TabWrapperComponent,
    TabComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {

  constructor(private injector: Injector) {
    const tabWrapper = createCustomElement(TabWrapperComponent, {injector: injector});
    customElements.define('custom-tab-wrapper', tabWrapper);
    const tabComponent = createCustomElement(TabComponent, {injector: injector});
    customElements.define('anb-tab', tabComponent);
  }
}

我知道我可以在没有 @ContentChildren 的情况下解决此问题,但我想在 CustomComponent 中使用此功能。 所以我的问题是:是否可以使用@ContentChildren / ViewChildren。 如果不是,有什么替代方案?

感谢您的帮助

丹尼尔

【问题讨论】:

    标签: angular web-component angular6


    【解决方案1】:

    Rob Worlmald 回答了我作为 Twitter 消息发送给他的问题。我想与社区分享结果:

    他回答了 Directives 和 ContentChild / ContentChildren 是否按以下方式工作的问题:

    不,他们没有 - 在当前视图中,引擎查询是静态的。在 一般,因为您可能会投射任何一个香草 DOM 节点或其他(Angular)自定义元素,您可以使用 查询选择器(全部)

    这基本上意味着我们可以使用 document.querySelector() 在 angular-livecycle 内或外部选择子级。在我个人看来,在 Angular 之外获取它似乎是更简洁的方法,因为不会使用几行额外的行,但仍会在 Angular 应用程序中执行。我会做一些研究。

    可以在此处找到有关此主题的进一步讨论和可能的解决方法: https://twitter.com/robwormald/status/1005613409486848000

    他继续说:

    你可以结合 https://developer.mozilla.org/en-US/docs/Web/Events/slotchange ... 近似相同的行为

    并以未来可能更清洁的解决方案结束:

    在 ivy(v7 或之后不久)中,我们可能会创建查询系统 更灵活和动态

    将在不久的将来使用 querySelectorAll 更新我的解决方案。

    【讨论】:

    猜你喜欢
    • 2020-06-08
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2019-02-07
    • 2021-04-25
    • 2018-10-20
    • 2023-03-10
    • 2018-10-31
    相关资源
    最近更新 更多