简体   繁体   English

打字稿内的angular 4.3(click)语法

[英]angular 4.3 (click) syntax inside typescript

I have a person component that looks something like this (very simplified): 我有一个看起来像这样的人组件(非常简化):

person.component.html 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 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. 当我单击“更多”按钮时,将触发more(id),并显示有关此人的更多信息。 So that's working. 这样就可以了。

But when I click the change button, change() never fires. 但是,当我单击更改按钮时,change()永远不会触发。 I know there's a better way and jquery needs to go, but I'm just not finding an example yet. 我知道有一个更好的方法,需要使用jquery,但是我还没有找到一个例子。

Thanks, 谢谢,


Heh. 嘿。 I knew jQuery was the wrong way to go, but sometimes I get frustrated and just want to get something to work. 我知道jQuery是错误的方法,但有时我会感到沮丧,只是想让某些事情起作用。

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. 我认为它与Angular的思维方式很接近,因此在这里添加它。

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 全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 全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. 唯一不成角度的部分是显示卡片主体的jquery。 I could use angular to just toggle classes, but I wanted to add the delay so it wasn't as abrupt. 我可以使用angular来切换类,但是我想添加延迟,这样就不会那么突然了。 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 替换剩余的jQuery切换功能
  • add aria-live and aria-announce to the right elements 将aria-live和aria-announce添加到正确的元素
  • 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! 谢谢邓肯!

You need to use angular to update the DOM. 您需要使用angular更新DOM。 HTML inserted using jQuery won't have been compiled to use any of your angular directives. 使用jQuery插入的HTML不会被编译为使用任何角度指令。

<div *ngfor='let current of users'>
  <p>{{current?.name}} <a (click)='more(current?.id)'>Click for more</a>
   <span *ngIf="wantMore[current?.id]">
       more info
       <button class='btn btn-primary btn-sm' (click)="changeCurrent()">
   </span>
  </p>
</div>

Then in your code: 然后在您的代码中:

export class Person {
  public wantMore = {};
  constructor() { }
  more(id: any){
    this.wantMore[id] = true;
  }
  changeCurrent() {
    console.log('hello world', this);
  }
}

try this: 尝试这个:

let response = `more info <button id='myIid' class='btn btn-primary btn-sm'>`;
$('#' + id + '_info').html(response);
var el = this.elementRef.nativeElement.querySelector('#myIid');
if(el) {
    el.addEventListener('click', this.changeCurrent.bind(this));
}

Besides, i saw you invoke changeCurrent function, but called your function change ... 此外,我看到您调用changeCurrent函数,但是称您的函数为change ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM