簡體   English   中英

Angular 6 在 AngularElements 中使用 ContentChildren/ViewChildren - CustomComponents

[英]Angular 6 using ContentChildren/ViewChildren in AngularElements - CustomComponents

我正在嘗試新的 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

以下是主要文件:

索引.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。 如果不是,有哪些替代方案?

謝謝你的幫助

丹尼爾

Rob Wolmald回答了我的問題,我將其作為 Twitter 消息發送給了他。 我想與社區分享結果:

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

不,他們沒有 - 在當前的視圖引擎中查詢是靜態的。 通常,因為您可能會投影普通 DOM 節點或其他(Angular)自定義元素,所以您可以只使用 querySelector(All)

這基本上意味着我們可以使用 document.querySelector() 在 angular-livecyclce 內或外部選擇孩子。 在我個人看來,在 Angular 之外獲取它似乎是更簡潔的方法,因為不會使用幾行額外的行,但仍會在 angular 應用程序中執行。 我會做一些研究。

可以在此處找到有關此主題的進一步討論和可能的解決方法: https : //twitter.com/robwormald/status/1005613409486848000

他繼續:

您可以將其與https://developer.mozilla.org/en-US/docs/Web/Events/slotchange結合使用……以近似相同的行為

並以將來可能更清潔的解決方案結束:

在 ivy(v7 或之后不久)中,我們可能會使查詢系統更加靈活和動態

將在不久的將來使用 querySelectorAll 更新我的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM