I have a person component that looks something like this (very simplified):
person.component.html
<div *ngfor='let current of users'>
<p>{{current?.name}} <a (click)='more(current?.id)'>Click for more</a>
<span [id]='current?.id + "_info"'></span>
</p>
</div>
person.component.ts
export class Person {
constructor() { }
more(id: any){
let response = `more info <button class='btn btn-primary btn-sm' (click)="changeCurrent()">`;
$('#' + id + '_info').html(response);
}
change() {
console.log('hello world', this);
}
}
When I click the more button, more(id) fires and it shows more information about the person. So that's working.
But when I click the change button, change() never fires. I know there's a better way and jquery needs to go, but I'm just not finding an example yet.
Thanks,
Heh. I knew jQuery was the wrong way to go, but sometimes I get frustrated and just want to get something to work.
Duncan gave me the clue to what I finally came up with. I think it is close to the Angular way of thinking, so I'm adding it here.
A better description of the example I'm playing with: A veterinary clinic has multiple vets, and each vet has multiple patients. A web page displays a list of vets. Clicking on a vet's name displays a list of the patients, with a button next to the patient name to toggle the patient's status, Current /Not Current.
all-vets.component.ts
export class AllVetsComponent implements OnInit {
vets: any = [];
patients: any = [];
displayPatients: any = [];
patientsRetrieved: boolean = false;
constructor(private http: Httppatient) { }
ngOnInit() {
// hit a web api, parse the data into this.vets and this.patients
}
getAllPatients(vetID: number): any[] {
// hit web api and get just the patients for the vet id
}
getPatients(vetID: number): void {
this.patientsRetrieved = false;
this.displayPatients[vetID] = [];
this.displayPatients[vetID] = getAllPatients(vetID);
this.patientsRetrieved = true;
$('#' + vetID + '_patients').toggle(500); // yes, still jQuery, but used for animations
}
showPatients(): boolean{
return this.patientsRetrieved;
}
changeStatus(patientID: number): void{
// find the patient with that id and toggle the currentPatient value
// post the change back to the api so it can go in the db
}
}
all-vets.component.html
<div class='card' *ngFor='let vet of vets'>
<div class='card-header' role='tab' [id]='vet?.vet_id'>
<a (click)='getAllPatients(vet?.vet_id)'
class="collapsed"
data-toggle="collapse"
(href)='"#" + vet?.vet_id'
aria-expanded="false"
>
{{vet?.vet_first_name}} {{vet?.vet_last_name}}
</a>
</div>
<div [id]='vet?.vet_id + "_patients"'
class="collapse hide" role="tabpanel"
[attr.aria-labelledby]='vet?.vet_id' [attr.data-parent]='"#" + vet?.vet_id'>
<div class="card-body patient-display">
<div class='container-fluid'>
<div class='row patient-listing patient-listing-header'>
<span class='patient-name col'>Name</span>
<span class='current-patient col'>Change Status</span>
</div>
<ng-template ngIf='showPatients()'>
<div class='row patient-listing' *ngFor='let patient of patients'>
<span class='patient-name col ' [ngClass]="{'currentpatient': patient.current_patient === 1, 'notpatient': patient.current_patient !== 1}">
{{patient?.name}}
</span>
<span class='patient-owner col'>
{{patient?.owner}}
</span>
<button class='btn btn-primary btn-sm' (click)='changeStatus(patient?.name)'>
<span *ngIf='patient.current_patient'>
Current
</span>
<span *ngIf='!patient.current_patient'>
Not Current
</span>
</button>
</span>
</div>
</ng-template>
</div>
</div>
</div>
</div>
I've removed extraneous details and changed names to protect the innocent.
This works for me. The only non-angular piece is the jquery that displays the card body. I could use angular to just toggle classes, but I wanted to add the delay so it wasn't as abrupt. There's probably a way to do that as well; I just haven't learned it yet. Clicking the button correctly updates the button text and changes the style of the patient's name, and that's the general behavior I was after.
Todo:
- replace the remaining jQuery toggle function
- add aria-live and aria-announce to the right elements
- add aria-role and other aria as appropriate
- use all of the complicated real world data instead of the proof of concept stuff
Thanks Duncan!