3
respostas

Remove wrapping de componente angular

Olá pessoal estou tentando desenvolver 2 componentes reusaveis para um dropdown (select do html) eu espero como sintaxe final para o componente ser montado o seguinte:

<ui-select>
  <ui-option *ngFor="let team of teams" [value]='team.id'>{{team.value}}</ui-option>
</ui-select>

Eu desenvolvi os seguintes componentes:

select.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'ui-select',
  templateUrl: './select.component.html'
})
export class SelectComponent {


}

select.component.html

<select>
    <ng-content></ng-content>
</select>

option.component.ts

import { Component, Input } from '@angular/core';

@Component({
  selector: 'ui-option',
  templateUrl: './option.component.html'
})
export class OptionComponent {

   @Input()  value:any;

   constructor() {
    this.value = '';
   }

}

option.component.html

<option [value]="value"><ng-content></ng-content></option>

Mas a marcação final do html é gerada com o componente ui-option junto que faz o html quebrar para um select que espera imediatamente um option:

<ui-select _ngcontent-c0="">
   <select>
  <!--bindings={"ng-reflect-ng-for-of": "[object Object],[object Object"}-->
      <ui-option _ngcontent-c0="" ng-reflect-value="1">
           <option value="1">team 1</option>
      </ui-option>
      <ui-option _ngcontent-c0="" ng-reflect-value="2">
           <option value="2">team 2</option>
      </ui-option>
   </select>
 </ui-select>

O gostaria de remove esse wrapping gerando o componente:

<ui-select _ngcontent-c0="">
   <select>
  <!--bindings={"ng-reflect-ng-for-of": "[object Object],[object Object"}-->
           <option value="1">team 1</option>
           <option value="2">team 2</option>
   </select>
 </ui-select> 

Como eu conseguiria atingir esse objetivo ? Alguma ajuda ?

3 respostas

Boa noite, Jonatan! Como vai?

Eu entendi a sua dúvida e ainda poderia completar ela dizendo que, se vc reparar bem, o mesmo está ocorrendo com o componente ui-select! Eu tentarei te ajudar nisso, mas antes de mais nada, queria tirar uma dúvida com vc!

Pq vc está criando um componente para o select e para o option e não somente usando eles diretamente? Pergunto isso pq dependendo do caso a criação desses componentes pode se configurar em trabalho desnecessário pra vc. Entende?

Ola Gabriel. O intuito é padronizar uma suíte de componentes diversos mesmo que representem apenas extensões (super set) do que as próprias marcações que o html já oferece . Um reforço simples dessa abordagem é que se por exemplo amanha houver a decisão de que meu select agora vai ter várias animações eu não precisaria por exemplo criar uma diretiva entrar em vários htmls e acertar um a um para esse novo "default". Vejo muitas aplicações angular fazendo mixin de coisas que são componentes e coisas que são nativas e vejo varias desvantagens nesse tipo de abordagem pensando sobre alguns aspectos de aplicações multi modular e padronização corporativa.

Bom todo caso mesmo assim o meu maior objetivo seria entender como interagir com componentes Pai e Filho (select e option foi um exemplo) removendo esse wrapping quando necessário principalmente pensando que libs como o bootstrap quebram dependendo do componente utilizado por conta do flex. Não sei se fui claro na resposta de sua pergunta.

Opa, Jonatan! Como vai?

Entendi a sua situação! Então vamos lá! Esse wrapping a que vc se referiu se chama host element. Não é possível remover ele da geração do DOM então vc terá que acertar o visual do seu componente via CSS mesmo.

Uma estratégia que vc pode pensar é criar um componente ui-select que já encapsule os options dessa forma:

<ui-select items="teams">
</ui-select>

E no select.component.html ficaria assim:

<select>
    <option *ngFor="let team of teams" [value]='team.id'>{{team.value}}</option>
</select>

Talvez assim vc tenha o resultado que vc espera. O que acha?

Qualquer coisa é só falar!

Grande abraço e bons estudos!