Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Alteração de duas variaveis simultaneamente

Está ocorrendo um erro bizarro com o meu código. Eu estou recebendo uma variável como Input() e jogando os valors dela em uma variável auxiliar para fazer algumas mudanças sem mudar o original. Só que quando eu faço as mudanças no auxiliar, a variavel original também muda sem qualquer aviso. Alguém poderia me dizer o que está acontecendo?

3 respostas

Oi Felipe,

Não consigo te dizer exatamente sem ver seu código. Se puder, posta ele aqui :) Vou dar um chute por enquanto...

Consigo enxergar isso acontecendo caso as duas variáveis apontem pra um mesmo objeto:

let obj = {
    a: "oi"
}

let obj2 = obj

obj2.a = "tchau"

No caso acima, tanto obj2 quanto obj apontam pro mesmo objeto, então alterar a propriedade a afetará os dois:

obj.a === obj2.a

Só vou conseguir colocar uma parte do código. Espero que seja o bastante

  @Input() vigenciaConfiguracao: any;
  @Input() editMode: boolean;

  private arrayAux:any;
  private listaEstagio: Array<any>= [];

  constructor(private defaultSv: ServiceDefault) {
  }

  ngOnInit() {
    console.log(this.vigenciaConfiguracao)
    this.editMode= true;

    //Carrega a lista de estágios junto com a opção padrão
    this.defaultSv.getServiceGenerico("/entity/get/Default/view/EstagioViewEntity", true).then(resultado=> {
      this.listaEstagio.push({
        descricao: "Selecione um estágio...",
        id: null
      });
      this.listaEstagio.push(...resultado.entity);
      //console.log("Lista de estágios: ", this.listaEstagio);
    }).catch(erro=>{
      console.log(erro);
    });
    console.log(this.vigenciaConfiguracao)
    this.arrayAux = this.vigenciaConfiguracao; <== Aqui é onde o arrayAux deve receber os valores do Input
    this.converterDatasTemplate();
  }

  //Faz as conversões das datas que serão carregadas no template para modelo NgbStruct
  private converterDatasTemplate(){
    this.arrayAux.vigencias.forEach(vigencia => {
      let dataIniConv= new Date(vigencia.dataInicio).toISOString().substr(0, 10);
      let datePickObjInicio= {
        year: parseInt(dataIniConv.substr(0, 4)),
        month: parseInt(dataIniConv.substr(5, 2)),
        day: parseInt(dataIniConv.substr(8, 2))
      };
      vigencia.dataInicio= datePickObjInicio;

      if(vigencia.dataFim){
        let dataFimConv= new Date(vigencia.dataFim).toISOString().substr(0, 10);
        let datePickObjFim= {
          year: parseInt(dataFimConv.substr(0, 4)),
          month: parseInt(dataFimConv.substr(5, 2)),
          day: parseInt(dataFimConv.substr(8, 2))
        };
        vigencia.dataFim= datePickObjFim;
      }else{
        vigencia.dataFim= null;
      }
    });
    console.log(this.arrayAux);
  }

Ambos os arrays devem ter essa composição:

ativo: string;
    id: number;
    version: number;
    vigencias: [
        {
            estagio: any;
            dataInicio: any;
            dataFim: any;
            id: number;
            version: number;
        }
    ]

E esse é o template:

<tbody>
        <tr *ngFor="let vigencia of arrayAux; let i= index; let primeiro= first; let ultimo= last">
          <td>
            <select [compareWith]="compararEstagios" [(ngModel)]="vigencia.estagio" (ngModelChange)="atualizarConfigs($event, i, 'estagio')" [disabled]="!editMode">
              <option *ngFor="let estagio of listaEstagio" [ngValue]="estagio">{{estagio.descricao}}</option>
            </select>
          </td>
          <td>
            <div class="input-group">
              <input #dtInicio="ngbDatepicker" placeholder="dd/mm/aaaa" [(ngModel)]="vigencia.dataInicio" (ngModelChange)="atualizarConfigs($event, i, 'dtIni')"  ngbDatepicker [disabled]="!editMode">
              <div class="input-group-append">
                <button class="btn btn-outline-secondary" (click)="dtInicio.toggle()" type="button" [disabled]="!editMode">
                  <i class="fa fa-calendar" aria-hidden="true"></i>
                </button>
              </div>
            </div>
          </td>
          <td>
            <div class="input-group">
              <input #dtFim="ngbDatepicker" placeholder="dd/mm/aaaa" [(ngModel)]="vigencia.dataFim" ngbDatepicker [disabled]="!editMode">
              <div class="input-group-append">
                <button class="btn btn-outline-secondary" (click)="dtFim.toggle()" type="button" [disabled]="!editMode">
                  <i class="fa fa-calendar" aria-hidden="true"></i>
                </button>
              </div>
            </div>
          </td>
          <td>
            <div class="col-lg-1 botao-adicionar" *ngIf="!ultimo">
              <button type="button" class="btn btn-secondary"  (click)="removerVigencia(i)" ngbTooltip="Excluir" [disabled]="!editMode"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
            </div>
            <div class="col-lg-1 botao-adicionar" *ngIf="ultimo">
              <button type="button" class="btn btn-secondary" (click)="adicionarVigencia()" ngbTooltip="Adicionar" [disabled]="!editMode"><i class="fa fa-plus" aria-hidden="true"></i></button>
            </div>
          </td>
        </tr>
      </tbody>
solução!

Encontrei um código JQuery que faz o clone dos valores mas sem referenciar outro objeto.

arrayAux =$.extend(true, {},  obj);

Mais informações aqui: https://debugmode.net/2013/10/31/merge-objects-using-extend-in-jquery/

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software