• 父组件监听子组件的事件


    子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。

    子组件的 EventEmitter 属性是一个输出属性,通常带有@Output 装饰器,就像在 VoterComponent 中看到的。

    component-interaction/src/app/voter.component.ts

    import { Component, EventEmitter, Input, Output } from '@angular/core';
    
    @Component({
      selector: 'app-voter',
      template: `
        <h4>{{name}}</h4>
        <button (click)="vote(true)"  [disabled]="didVote">Agree</button>
        <button (click)="vote(false)" [disabled]="didVote">Disagree</button>
      `
    })
    export class VoterComponent {
      @Input()  name: string;
      @Output() voted = new EventEmitter<boolean>();
      didVote = false;
    
      vote(agreed: boolean) {
        this.voted.emit(agreed);
        this.didVote = true;
      }
    }

    点击按钮会触发 true 或 false(布尔型有效载荷)的事件。

    父组件 VoteTakerComponent 绑定了一个事件处理器(onVoted()),用来响应子组件的事件($event)并更新一个计数器。

    component-interaction/src/app/votetaker.component.ts

    import { Component }      from '@angular/core';
    
    @Component({
      selector: 'app-vote-taker',
      template: `
        <h2>Should mankind colonize the Universe?</h2>
        <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
        <app-voter *ngFor="let voter of voters"
          [name]="voter"
          (voted)="onVoted($event)">
        </app-voter>
      `
    })
    export class VoteTakerComponent {
      agreed = 0;
      disagreed = 0;
      voters = ['Narco', 'Celeritas', 'Bombasto'];
    
      onVoted(agreed: boolean) {
        agreed ? this.agreed++ : this.disagreed++;
      }
    }

    测试一下!

    测试确保点击 Agree 和 Disagree 按钮时,计数器被正确更新。

    component-interaction/e2e/src/app.e2e-spec.ts
    // ...
    it('should not emit the event initially', function () {
      let voteLabel = element(by.tagName('app-vote-taker'))
        .element(by.tagName('h3')).getText();
      expect(voteLabel).toBe('Agree: 0, Disagree: 0');
    });
    
    it('should process Agree vote', function () {
      let agreeButton1 = element.all(by.tagName('app-voter')).get(0)
        .all(by.tagName('button')).get(0);
      agreeButton1.click().then(function() {
        let voteLabel = element(by.tagName('app-vote-taker'))
          .element(by.tagName('h3')).getText();
        expect(voteLabel).toBe('Agree: 1, Disagree: 0');
      });
    });
    
    it('should process Disagree vote', function () {
      let agreeButton1 = element.all(by.tagName('app-voter')).get(1)
        .all(by.tagName('button')).get(1);
      agreeButton1.click().then(function() {
        let voteLabel = element(by.tagName('app-vote-taker'))
          .element(by.tagName('h3')).getText();
        expect(voteLabel).toBe('Agree: 1, Disagree: 1');
      });
    });
    // ...
  • 相关阅读:
    采购申请 POCIRM-001:ORA-01403: 未找到任何数据
    前后端交互技术有哪些
    React实现类似淘宝tab居中切换效果
    CSS通过text-transform实现大写、小写和首字母大写转换
    从浏览器内部运行机制看性能优化
    设置网页浏览器标签小图标
    前后端分离的优缺点
    修改input搜索框默认叉号的样式为自定义图片
    编写优秀CSS代码的8个策略
    css如何设置不可复制?
  • 原文地址:https://www.cnblogs.com/telwanggs/p/13399090.html
Copyright © 2020-2023  润新知