Kod JS oddziałuje wyłącznie na jeden komponent(angular 2+), zamiast per komponent

0

Zrobiłem sobie w aplikacji angular 2+ preview ładowania zdjęć.. wstawiłem to w komponent i powieliłem 3 razy.. jak klikam na element 1, 2 lub 3 to działanie jest takie samo. Mianowicie: ładuje mi zdjęcie tylko do pierwszego komponentu( krótki gif w załączniku). Czym to jest spowodowane i jak to naprawić? Kod poniżej

parent HTML:

<div class="form-inline">
                <app-advert-photo-element [photoNumber]="1"></app-advert-photo-element>
                <app-advert-photo-element [photoNumber]="2"></app-advert-photo-element>
                <app-advert-photo-element [photoNumber]="3"></app-advert-photo-element>
</div>

app-advert-photo-element HTML:

<div class="polaroid">
  <label for="photo" class="cursor-pointer">
    <img [src]="url" class="img-fluid" alt="">
  </label>
  <div class="img-title-bot">
    Nr {{photoNumber}}.
  </div>
  <input type="file" id="photo" (change)="onSelectFile($event)">
</div>

app-advert-photo-element TS:

export class AdvertPhotoElementComponent implements OnInit {

  @Input()
  protected photoNumber;

  protected url = '';

  constructor() {
  }

  ngOnInit() {
  }

  onSelectFile(event: any) {
    if (event.target.files && event.target.files[0]) {
      const reader = new FileReader();

      reader.onload = (onLoadEvent: any) => {
        this.url = onLoadEvent.target.result;
      };

      reader.readAsDataURL(event.target.files[0]);
    }
  }
}
0

puk, puk, up :D

1

Wszystkie trzy mają to samo id, więc przeglądarka siłą rzeczy wczytuje do pierwszego napotkanego.

0

@Patryk27: jakie jest rozwiązanie? nadanie id elementom nic nie zmienia

                <app-advert-photo-element id="a" [photoNumber]="1"></app-advert-photo-element>
                <app-advert-photo-element id="b" [photoNumber]="2"></app-advert-photo-element>
                <app-advert-photo-element id="c" [photoNumber]="3"></app-advert-photo-element>
2
<input type="file" id="photo" (change)="onSelectFile($event)">

Ten fragment nadaje to samo id każdemu inputowi - pomyśl, jak można to zmienić.

0

Zreprodukowałem problem
https://stackblitz.com/edit/angular-h4df6q
Wychodzi na to, że problem jest w CSS komponentu AdvertPhotoElementComponent. Bez css działa. Tylko co CSS ma tu do rzeczy?

2

Kolega już Ci napisał co jest nie tak. I nie chodzi o nadanie Id wygenerowanym przez ciebie komponentom a id inputom którym generujesz w każdym komponencie.
Czyli majac:

<input type="file" id="photo" (change)="onSelectFile($event)">

Za id inputa podstawiasz jakies swoj identyfikator np.

<input type="file" id="{{photonumber}}" (change)="onSelectFile($event)">

I przy okazji zmieniasz oznaczenia labelom:

 <label for="{{photoNumber}}" class="cursor-pointer">
    <img [src]="url" class="img-fluid" alt="">
  </label>

Nie wiem o co Ci chodzi z css ale to raczej nie ma nic wspólnego z błędem który masz w markupie.

1

właśnie, że usuwając css, ten błąd nie występiuje >

input[type='file'] {
  display:none;
  max-width: 1px;
  max-height: 1px;
}

Tutaj celowo ukrywasz input poprzez display. Nie mając tego, masz bezpośredni dostęp do inputa i poprzez change event bezpośrednio zmnieasz atrybut src elementu img wewnątrz komponentu za pomocąonSelectFile().

Teraz mając:

<label for="photo" class="cursor-pointer">
    <img [src]="url" class="img-fluid" alt="">
  </label>
<input type="file" id="photo" (change)="onSelectFile($event)">

Wiążesz bezpośrednio label z tym konkrentym inputem o id równym photo. Teraz mając takie oznaczenia, nie ważne na który label(input) klikniesz i tak dostaniesz obrazek w pierwszym możliwym labelu gdzie atrybut for bedzie równy "photo" bo każdy twój input jest powiązany z tym samym labelem. Nie mając css masz dostęp do każdego inputu i omijasz label i ustawiasz atrybut src elementu img bezpośednio.
Wyszło masło maślane ale mam nadzieję że już załapiesz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1