0
  1. It's just simple divs with text
  2. I don't need and don't want use/create other components
  3. And without querySelectors
  4. Number of elements might be more then 50.
  5. Text can be defferent, cities names, for example

Is there a way for

  • get all elements with link class
  • add by clicking to one of them active class to target
  • and remove active class from others So, we have 3 same divs, but with active class only one.

__

Also, I need to chane active class for another 3 elements - image class

This is generaly tabs. But with very simple layout:

      <div class="links">
        <div class="link active">
          Link 1
        </div>
        <div class="link">
          Link 2
        </div>
        <div class="link">
          Link 3
        </div>
      </div>

      <div class="images">
        <div class="image active">
          Image 1
        </div>
        <div class="image">
          Image 2
        </div>
        <div class="image">
          Image 3
        </div>
      </div>
Spawnet
  • 53
  • 6

2 Answers2

2

component HTML:

<div class="links">
  <div *ngFor="let i of [1,2,3]" class="link" [class.active]="clickedIndex === i" (click)="clickedIndex = i"> Link {{ i }} </div>
</div>

component class:

@Component({
  selector: 'app-root',
})
export class AppComponent {
  clickedIndex = 0;
}
Stavm
  • 7,833
  • 5
  • 44
  • 68
  • Text will be names of cities. For example London, Moscow, New York. And images with this city in another block. Also, there can be 50 cities. – Spawnet May 02 '23 at 17:23
  • 1
    sounds good, what is your question ? – Stavm May 02 '23 at 17:24
  • As I can see 1) Text to div adds with loop. Now It can be only Link . But I need defferent fixed words - London, Moscow, etc. 2) If i need 50 links, then I need to add array like *ngFor="let i of [1,2,3,4,5,6,7,8,9,10,11,12 and till 50]" ? – Spawnet May 02 '23 at 17:29
  • And also, main question is - is ther a good, simple way to get elemets by class like in pure JS - querySelector('.link') = and then operate with element as I want? – Spawnet May 02 '23 at 17:31
  • how can I remove active class from element if I click on active? So I need all of them without active class. – Spawnet May 31 '23 at 14:10
0

You can totally do like @Stavm suggested in his answer (upvoted it), but since you have an array of cities (or different strings) you should just extract the index he mentioned a bit differently. An example:

Say in your component you have an array: public cities = ['London', 'Moscow', 'Stockholm', ...];

You can get the index in the for loop like this: let i = index;

<div class="links">
  <div *ngFor="let city of cities; let i = index" class="link" [class.active]="clickedIndex === i" (click)="clickedIndex = i">{{city}} </div>
</div>

UPDATE:

After your comments I add an update that will come closest to a query selector. You could consider using @ViewChildren. Check the official Angular documentation on @ViewChildren here. Also checkout the example given in this answer on another question. In your example it would be something like this:

In your component:

@ViewChildren("linkDivs") linkDivs: QueryList<ElementRef>;
@ViewChildren("imageDivs") imageDivs: QueryList<ElementRef>;

In your template:

<div class="links">
  <div #linkDivs *ngFor="let city of cities; let i = index" class="link">{{city}}</div>
</div>

<div class="images">
  <div #imageDivs *ngFor="let image of images; let i = index" class="link">{{image}}</div>
</div>

Now you get an array with the ElementRef to all link divs in that variable in your component and in the template you can grab it with linkDivs[i]. Not sure what exactly you want to do with it further though. I leave that up to you.

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • So, in general, there is no simple way to get elemets by class like in pure JS - querySelector('.link') - get some array and then do stuff? – Spawnet May 02 '23 at 20:29
  • I would say it is the wrong approach, since `querySelector('.link')` will be executed after the DOM has been rendered. In the example you add the class before the view is rendered so IMO it is a better solution. But if you want something like that you could have a look at `@ViewChildren`. Check [the offical Angular documentation here](https://angular.io/api/core/ViewChildren#description) – Wilt May 02 '23 at 20:54
  • @Spawnet As an addition to the comment above; you could checkout [the example given in another answer on a similar topic](https://stackoverflow.com/a/53016746/1697459). – Wilt May 02 '23 at 21:05
  • Not sure what exactly you want to do with it further though. - simple tabs: when you click to London => image with London.jpg showed. And the same action for the rest 50 cities. – Spawnet May 03 '23 at 11:10