5

I want the display the user an image, with a varying number of divs (depending on the number of faces detected) which should be clickable (a click on a face will show some attributes for that particular face).

So ideally I would like to create some divs (or buttons) around each face and have something like (click)="divClicked()" for each element. However,(click) isn't a legit attribute, so, for example, trying something like

d3.select('button').attr('(click)','onClickMe()');

gives an error. onclick is a legit attribute, but by using it I think I should break the way Angular wants me to work (as putting the function inside the component's ts file gives the error onClickMe is not defined).

The very best workaround I could come up with is to assign an id to each div and then do something like

document.getElementById('b1').onclick=this.onClickMe;

but that feels like bad coding.

So, what's the clean way to do that?

6
  • Do you have a Stackblitz for this? Commented Sep 2, 2018 at 12:26
  • @SiddharthAjmera No, my IDE is Visual Studio Code (and my OS is Ubuntu). Commented Sep 2, 2018 at 12:28
  • I mean can you create a sample project replicating this issue on StackBlitz? stackblitz.com/fork/angular Commented Sep 2, 2018 at 12:29
  • Oh! Later on if that's necessary (as I will need to create some fake data rather than copy the entire code dealing with the json data from the server) but the question itself is about clean coding rather than about a specific project/code. Commented Sep 2, 2018 at 12:35
  • Why don't you think that (click) is legit? Commented Sep 2, 2018 at 12:59

1 Answer 1

14

I think you should create the div elements by adding a loop with ngFor to your template to display your divs. Of course they may be CSS-styled, based on some properties you have determined beforehand (in particular the CSS properties left and top are useful here). Of course you can add a (click)-event to those divs too.

To do this, your component should hold a list of objects to display which you may update when necessary. Furthermore it should offer a method which gets called when the user wants to see details of a particular face. The template then only cares for turning those objects into a HTML structure and bind the callbacks.

Structurally something similar to the following will occur in your template:

<div
    *ngFor="let face of faces; index as i"
    (click)="showFaceDetails(i)"
    [style.left.px]="face.x"
    [style.top.px]="face.y"
></div>
Sign up to request clarification or add additional context in comments.

1 Comment

That was helpful, althought I must say that since the page I'm building is responsive (so left top etc. have to be based on the actual image shape in relation to the original image) I don't think that setting those attributes with ngFor is feasible. (Actually right now I set them with an img.onload function which feels like bad coding by itself, but I'm not sure if actual clean coding is possible when it comes to front end :P)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.