ViewChild(ren) x document.getElementById - In ngFor and style class

Hello, I need to get a specific element inside several, dynamically created inside an ngFor and assign it a different style class. For this I am using in @VielChild, but it can not identify the specific element to perform the css change on it.

Below is the code Html:

  <ion-grid no-padding>
    <ion-row>
      <ion-col col-6 *ngFor="let produto of produtos; let i = index" no-padding align-items-center>
        <ion-card no-padding>
          <img [src]="produto.foto" />
          <button [ngClass]="produto.qtdFavorito > 0 ? 'ativado' : 'desativado'" ion-fab mini class="favorito" (click)="inserirItemNoFavorito(produto.id,i)" #botFavorito >
            <ion-icon name="heart"> </ion-icon>
          </button>
          <ion-card-content>
            <p>
              {{produto.descricao}}
            </p>
            <ion-list no-padding>
              <ion-item no-padding>
                <h3>A partir de:</h3>
                <h1>{{produto.minimo | currency : "R$ "}}</h1>
              </ion-item>

            </ion-list>

          </ion-card-content>
          <div style="padding: 5px" class="buttonComprar">
            <button ion-button icon-end block color="secondary" (click)="listarProdutosCompra(produto.id, produto.foto, produto.descricao)">
              Comprar
              <ion-icon name="cart"></ion-icon>
            </button>
          </div>

        </ion-card>
      </ion-col>
    </ion-row>
  </ion-grid>

The element I want to get is the #botFavorite that refers to a button, it is in it that I want to pass the css style, but using the @ViewChild all the button type elements that were created will be modified, like doing this only in the element that I clicked on ?

I saw this post where they use getElementById, but I can not insert or remove a style class in the variable that gets this element.

My configuration is:

Angular CLI: 1.7.4
Node: 9.6.0
OS: darwin x64
Angular: 5.2.11

ionic (Ionic CLI) : 4.1.0 (/usr/local/lib/node_modules/ionic)
Ionic Framework : ionic-angular 3.9.2
@ionic/app-scripts : 3.1.10

1 Like

I really dislike using @ViewChild in situations like this, because presentation stuff (like styling) should be in templates, not controllers. You already have conditional classes being set on that button; why can’t you just extend that to do whatever conditional styling is required?

This is a button to put the item as a favorite, it will be true or false, this boolean attribute comes from the database. If the product is favorite then the color of the button is different, this works fine, the problem is that to change the color after the click is necessary a reloader on the page, and this I do not want to do to avoid delay in a list that has by example 1000 items. Then decide that clicking the button will put the product in the favorite, but will not reload the page avoiding a new request, then to identify that the product has entered the favorite it manually changed the style of the element. That is, as long as the user does not reload the button is already signaling that the product is in the favorite, and when the user gives the reload, the information already comes from the database itself.

For exemple, the button favorite in this site, I want it that way :

Leaving aside the wisdom of 1000-item lists in general, I don’t understand what you are talking about with reloading of pages and new requests. Angular change detection is going to be both more readable and do a better job of dealing with a structure like the following than any homebrew manual DOM manipulation would, which seems to be more or less what you are asking for:

fruits = [
  {name: "apple"},
  {name: "banana"},
  {name: "cherry"},
];

mogrifyColor(fruit): void {
  fruit.color = fruit.color === 'red' ? 'blue' : 'red';
}
<ion-item *ngFor="let fruit of fruits">
  <button ion-button [style.background-color]="fruit.color" (click)="mogrifyColor(fruit)">{{fruit.name}}</button>
</ion-item>

Hi, tnks. I understood what you are suggesting. But, for example, how to start the “product” object with the button informing if it is already in the favorite or not? In the example where you put all objects already initialized without any custom style, which is the default, just receive the first customization after the click. In my case, objects are not initialized to the same pattern, this varies depending on whether or not it is a favorite. When I click it it will vary according to the first style loaded, for example, if the object was created being a favorite, it will uncheck the button, otherwise it will mark it. Where to load the initial style?

Seed whatever property of each “product” object is being used with whatever is coming from the database indicating whether it has been favored.

I confess that since you posted the example I studied how to implement it, you are covered in reason! The objects have already been loaded in the first request with the initial properties. Now I can manipulate the objects locally and only after completing the post request. I implemented your example, it worked perfectly, thank you very much.