Использование компонента в качестве пользовательского элемента и в качестве углового компонента - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь использовать компонент Angular в качестве пользовательского элемента, чтобы я мог динамически добавлять его в DOM, и он автоматически загружался, но мне также нужен этот компонент как часть шаблона другого компонента.

Я зарегистрировал компонент Description как пользовательский элемент, и он корректно загружается в любое время, когда я добавляю в dom следующее:

<app-description text="Some description text..."></app-description>

Но, если я хочу использовать этот компонент как частьшаблона компонента Header (с правильно установленным атрибутом descriptionText) У меня не отображается описание.Я использую это так:

<app-description text="{{descriptionText}}"></app-description>

Я также пытался:

<app-description [text]="descriptionText"></app-description>

и

<app-description text="descriptionText"></app-description>

, но я не получил ожидаемогорезультат в любом случае.

Итак, мой вопрос: есть ли способ определить угловой компонент как пользовательский элемент, а также иметь возможность включить его в шаблон любого углового компонента?

Редактировать: Я поместил console.log () внутри метода ngOnInit в компонентах Header и Description, и я получаю его в консоли:

enter image description here

Кажется, что компонент инициализируется два раза, а во втором текст имеет значение undefined?

Описание компонента:

@Component({
  selector: 'app-description',
  templateUrl: './description.component.html',
  styleUrls: ['./description.component.css']
})
export class DescriptionComponent implements OnInit {
  @Input() text: String;

  constructor() {}

  ngOnInit() {
    console.log('text:', this.text)
  }
}

Шаблон описания:

<div class="description">
    <h3>{{ text }}</h3>
</div>

Компонент заголовка:

  @Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.less']
  })
  export class HeaderComponent implements OnInit {
    @Input() title: String;
    @Input() subtitle: String;
    @Input() descriptionText: String;

    constructor() {}

    ngOnInit() {
      console.log('descriptionText:', this.descriptionText)
    }
  }

Шаблон заголовка:

<div class="header flex-container">
    <h1>{{ title }}</h1>
    <h2>{{ subtitle }}</h2>
    {{descriptionText}} <!-- shown correctly! -->
    <app-description text="{{descriptionText}}"></app-description>
</div>

Модуль:

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    DescriptionComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [],
  entryComponents: [
    AppComponent,
    HeaderComponent,
    DescriptionComponent
  ],
  schemas : [
    CUSTOM_ELEMENTS_SCHEMA
  ]
}) 

export class AppModule {
  constructor(private injector: Injector) {
    this.registerCustomElements();
  }

  ngDoBootstrap() {}

  registerCustomElements() {
    const HeaderElement = createCustomElement(HeaderComponent, {injector: this.injector});
    customElements.define('app-header', HeaderElement);

    const DescriptionElement = createCustomElement(DescriptionComponent, {injector: this.injector});
    customElements.define('app-description', DescriptionElement);
  }
}

Я использую угловые пользовательские элементы, представленные в Angular 6

Спасибо!

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Я нашел решение!

Если мы увидим мой description.component.ts, HTML-тег для этого компонента будет app-description :

@Component({
  selector: 'app-description',
  ...

Ив моем app.module.ts я регистрирую DescriptionComponent как угловой элемент, подобный этому:

const DescriptionElement = createCustomElement(DescriptionComponent, {injector: this.injector});
customElements.define('app-description', DescriptionElement);

Обратите внимание, что я объявляю элемент с тем же тегом, что и компонент.Я изменил это на:

const DescriptionElement = createCustomElement(DescriptionComponent, {injector: this.injector});
customElements.define('app-descriptions', DescriptionElement);

, и теперь я могу использовать пользовательский элемент в любом HTML-файле, например так:

<body>
  <app-descriptions text="Probando 1"></app-descriptions>
</body>

и использовать DescriptionComponent внутри моего шаблона заголовка, например:

 <app-description text="{{descriptionText}}"></app-description>

Мой вывод таков: Объявите свой угловой элемент с помощью другого тега HTML из тега HTML компонента.

Спасибо всем, кто сотрудничал!

0 голосов
/ 12 июня 2018

Хорошо, я решил использовать следующий код, проблема была связана с чем-то, связанным с вложенным кодом CSS, тогда вам нужно вставить в свой дочерний пользовательский элемент (в данном случае <app-description>) следующую строку encapsulation: ViewEncapsulation.None, и я изменилvar descriptionTest до description

description.component.ts

@Component({
  selector: 'app-description',
  templateUrl: './description.component.html',
  styleUrls: ['./description.component.css'],
  encapsulation: ViewEncapsulation.None
})

description.component.html

<div>
    {{text}}
</div>

header.component.ts

  @Input() title: String;
  @Input() subtitle: String;
  @Input() description: String;

header.component.html

    <div class="header flex-container">
      <h1>{{ title }}</h1>
      <h2>{{ subtitle }}</h2>
      {{description}} <!-- shown correctly! -->
      <app-description text="{{description}}"></app-description>
    </div>

**App.module.ts**

@NgModule({
  declarations: [
    AppComponent,      
    HeaderComponent,
    DescriptionComponent  
  ],
  imports: [
    BrowserModule,    
  ],  
  providers: [],
  entryComponents:[
    HeaderComponent,
    DescriptionComponent
  ],
  bootstrap: []
})
export class AppModule {
  constructor(private injector: Injector) {

  }

  ngDoBootstrap() {
    this.registerCustomElements();
  }

  registerCustomElements() {
    const DescriptionElement = createCustomElement(DescriptionComponent, {injector: this.injector});
    customElements.define('app-description', DescriptionElement);

    const HeaderElement = createCustomElement(HeaderComponent, {injector: this.injector});
    customElements.define('app-header', HeaderElement);       
  }

Index.html

 <app-root>
  </app-root>
  <app-description text="'HOLA!'"></app-description>

  <app-header title="Title"
      subtitle="Subtitle"
      description="DESCRIPTION"
  ></app-header>

src

output

репозиторий github с этимпример

...