3
respostas

BIND NÃO FUNCIONANDO DIREITO EM SELECT

Boa Noite Flavio,

Gostaria de uma grande ajuda, pois estou tendo um problema chato em relação a seguinte situação: (De forma resumida)

  • Possuo 2 selects
  • Ao selecionar os valores de 1 dos selects irá realizar uma buscar no servidor e preenchera o outro array o qual o select 2 possui uma ligação com o 'ngFor"

FRONT

<form class="col s12" [formGroup]="formParam" (ngSubmit)="createParam()">
  <div class="modal-content">
    <div class="row">

         <div class="input-field col s12 xl4" >
          <select id="otc-select" materialize="material_select" formControlName="category">
            <option value="" disabled></option>
            <option *ngFor="let ct of categories" [value]="ct.id" >{{ ct.name }}</option>
          </select>
          <label>Categoria</label>
        </div>
        <div class="input-field col s12 xl4">
          <select id="otc-subcategories" materialize="material_select" formControlName="subCategory">
            <option value="" disabled></option>
            <option *ngFor="let sbc of subCategories" [value]="sbc.id" >{{ sbc.name }}</option>
          </select>
          <label>Subcategorias</label>
        </div>
      </div>

COMPONENT:

export class TableParamsFormComponent implements OnInit {

  teste = 'sem valor';

  formParam: FormGroup;

  types: string[] = [];
  formats: string[] = [];
  groups: GroupParam[] = [];
  categories: CategoryParam[] = [];
  subCategories = null;

  constructor(private _tableParamsService: TableParamsService,
              private _formBuilder: FormBuilder) {}

  ngOnInit(): void {
    this._generateForm();
    this.openNewParam();
  }

  private _generateForm() {
    this.formParam = this._formBuilder.group({
            category: [null, [Validators.required]],
      subCategory: [null, [Validators.required]]
    });

    this.observableFields();
  }

  observableFields() {
    this.formParam.get('category').valueChanges
      .subscribe((value) => {
        console.log('### category ###');
        console.log(value);
        const id = Number.parseInt(value);
        this._getSubcategories(id);
    });

    this.formParam.get('subCategory').valueChanges
    .subscribe((value) => {
      console.log('### subcategory ###');
      console.log(value);
    });

    this.formParam.get('type').valueChanges
      .subscribe((value) => {
        console.log(value);
        console.log(this.formParam.controls['type']);
        // const fieldFormat = this.formParam.get('format').valid;
        // if (fieldFormat) this.formParam.get('value').enable();
        console.log(this.formParam);
    });

    this.formParam.get('format').valueChanges
      .subscribe((value) => {
        const fieldFormat = this.formParam.get('type').valid;
        if (fieldFormat) this.formParam.get('value').enable();
    });
  }

// Tentativa 2
  private _getSubcategories(id: number) {
    this.categories.forEach((category: CategoryParam) => {
      if (category.id === id) {
         let selected = true;
         let options = '';
         const subCategories: SubCategoryParam[] = category.subCategories;
         subCategories.forEach((subCategory) => {
           console.log(subCategory);
           options = options.concat(`<option value="${subCategory.id}" ${selected ? 'selected' : ''}>${subCategory.name}</option></br>`);
          //  selected = false;
         });

        console.log($('#otc-subcategories'));
        // $('#otc-subcategories').empty();
        $('#otc-subcategories').html(options);
      }
    });
  }

  openNewParam() {
    this._getInfo();
  }

  private _getInfo() {
    this._tableParamsService.getTypes()
        .then((types) => {
          this.types = types;
        });

    this._tableParamsService.getFormats()
        .then((formats) => {
          this.formats = formats;
        });

    this._tableParamsService.getGroups()
      .then((groups) => {
        this.groups = groups;
      });

    this._tableParamsService.getCategories()
      .then((categories) => {
        this.categories = categories;
    });

  }

O que está acotecendo, é que ao selecionar o valor no select "categoria", ele pega as subcategorias de dentro dele e joga para dentro do array de "subCategorias", só que o valor do select não muda automaticamente, só se for seleciona outro item em categoria, ai aparece, não entendo o que acontece.

Já com a "tentativa 2", o qual injeto diretamente um HTML novo, também ocorre um problema, só que dessa vez o HTML não está sendo alterado em alguns casos, EX:

- Seleciono "API", abre a subcategoria "MARKUP"
- Seleciono "EMAIL", abre a subcategoria "SECURITY, HOST"
- Seleciono "SERVER", o select mantem no campo os mesmo valores do "EMAIL", pois server também possui "SECURITY, USER" (ex), 

Fico no aguardo de uma ajuda, forte abraço.

3 respostas

Fala aí Frank, beleza? Bom, eu faria diferente, vamos lá:

Dentro do seu primeiro select de categorias faça um event bind para um método da sua classe:

<select (change)="getSubCategories($event)" id="otc-select" materialize="material_select" formControlName="category">

Dai, dentro da sua classe você busca as sub categorias dentro da categoria passada como parâmetro da função e atualiza o array

Se quiser, dá uma olhada nesse exemplo: https://codesandbox.io/s/00m0lz6r2w

Espero ter ajudado.

Obrigado pela resposta Matheus, só que meu problema não é necessariamente esse, e sim que ao adicionar novos valores no array o qual ele escutada (*ngFor), ele não atualiza nos valores do select,

(como se o próprio html do select não estivesse renderizando, mas quando abro o console do navegador e vejo os elementos, os valores estão dentro dos options, só não aparecem no select (Utilizo o MATERIALIZE))

Eu resolvi com "Eventos" o qual postarei depois aqui como resposta para que possa ajudar outras pessoas.

Precisaria entender melhor, vou fazer um exemplo depois utilizando o .subscribe do formGroup, acredito que deva ser algum problema nele.

Conforme o exemplo, eu faria diferente e sem a necessidade de eventos, porém, o importante é que você conseguiu resolver o problema.

Posta sim, vai ajudar a galera, abraços.