Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module:avatar): support image load error event #3893

Merged
merged 1 commit into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions components/avatar/avatar.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, DebugElement, ViewChild } from '@angular/core';
import { fakeAsync, tick, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { createFakeEvent } from 'ng-zorro-antd/core';

import { NzIconTestModule } from 'ng-zorro-antd/icon/testing';

Expand Down Expand Up @@ -38,11 +39,12 @@ describe('avatar', () => {
expect(context).not.toBeNull();
});
it('should tolerate error src', fakeAsync(() => {
const event = createFakeEvent('error');
expect(getType(dl)).toBe('image');
expect(context.comp.hasSrc).toBe(true);
// Manually dispatch error.
context.nzSrc = '';
context.comp.imgError();
context.comp.imgError(event);
tick();
fixture.detectChanges();
expect(getType(dl)).toBe('icon');
Expand All @@ -55,6 +57,26 @@ describe('avatar', () => {
expect(getType(dl)).toBe('image');
tick();
}));
it('should prevent default fallback when error src', fakeAsync(() => {
const event = createFakeEvent('error');
event.preventDefault();
expect(getType(dl)).toBe('image');
expect(context.comp.hasSrc).toBe(true);
// Manually dispatch error.
context.nzSrc = 'Invalid image src';
context.comp.imgError(event);
tick();
fixture.detectChanges();
expect(getType(dl)).toBe('image');
expect(context.comp.hasSrc).toBe(true);
context.nzSrc =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==';
tick();
fixture.detectChanges();
expect(context.comp.hasSrc).toBe(true);
expect(getType(dl)).toBe('image');
tick();
}));
it('#nzSrcSet', () => {
context.nzSrcSet = '1.png';
fixture.detectChanges();
Expand Down Expand Up @@ -164,27 +186,30 @@ describe('avatar', () => {
expect(getType(dl)).toBe('image');
});
it('should be show icon when image loaded error and icon exists', fakeAsync(() => {
const event = createFakeEvent('error');
expect(getType(dl)).toBe('image');
context.comp.imgError();
context.comp.imgError(event);
tick();
fixture.detectChanges();
expect(getType(dl)).toBe('icon');
}));
it('should be show text when image loaded error and icon not exists', fakeAsync(() => {
const event = createFakeEvent('error');
expect(getType(dl)).toBe('image');
context.nzIcon = null;
fixture.detectChanges();
context.comp.imgError();
context.comp.imgError(event);
tick();
fixture.detectChanges();
expect(getType(dl)).toBe('text');
}));
it('should be show empty when image loaded error and icon & text not exists', fakeAsync(() => {
const event = createFakeEvent('error');
expect(getType(dl)).toBe('image');
context.nzIcon = null;
context.nzText = null;
fixture.detectChanges();
context.comp.imgError();
context.comp.imgError(event);
tick();
fixture.detectChanges();
expect(getType(dl)).toBe('');
Expand Down
1 change: 1 addition & 0 deletions components/avatar/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ import { NzAvatarModule } from 'ng-zorro-antd/avatar';
| `[nzSrcSet]` | a list of sources to use for different screen resolutions | string | - |
| `[nzAlt]` | This attribute defines the alternative text describing the image | string | - |
| `[nzText]` | letter type avatar | `string` | - |
| `(nzError)` | handler when img load error, call the `preventDefault` method to prevent default fallback behavior | `EventEmitter<Event>` | - |
1 change: 1 addition & 0 deletions components/avatar/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ import { NzAvatarModule } from 'ng-zorro-antd/avatar';
| `[nzSrcSet]` | 设置图片类头像响应式资源地址 | string | - |
| `[nzAlt]` | 图像无法显示时的替代文本 | string | - |
| `[nzText]` | 文本类头像 | `string` | - |
| `(nzError)` | 图片加载失败的事件,调用 `preventDefault` 方法会阻止组件默认的 fallback 行为 | `EventEmitter<Event>` | - |
2 changes: 1 addition & 1 deletion components/avatar/nz-avatar.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<i nz-icon *ngIf="nzIcon && hasIcon" [type]="!oldAPIIcon && nzIcon" [ngClass]="oldAPIIcon && nzIcon"></i>
<img *ngIf="nzSrc && hasSrc" [src]="nzSrc" [attr.srcset]="nzSrcSet" [attr.alt]="nzAlt" (error)="imgError()"/>
<img *ngIf="nzSrc && hasSrc" [src]="nzSrc" [attr.srcset]="nzSrcSet" [attr.alt]="nzAlt" (error)="imgError($event)"/>
<span class="ant-avatar-string" #textEl [ngStyle]="textStyles" *ngIf="nzText && hasText">{{ nzText }}</span>
26 changes: 16 additions & 10 deletions components/avatar/nz-avatar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import {
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
Output,
Renderer2,
SimpleChanges,
ViewChild,
Expand Down Expand Up @@ -46,6 +48,7 @@ export class NzAvatarComponent implements OnChanges {
@Input() nzSrcSet: string;
@Input() nzAlt: string;
@Input() nzIcon: string;
@Output() readonly nzError = new EventEmitter<Event>();

oldAPIIcon = true; // Make the user defined icon compatible to old API. Should be removed in 2.0.
hasText: boolean = false;
Expand Down Expand Up @@ -80,17 +83,20 @@ export class NzAvatarComponent implements OnChanges {
return this;
}

imgError(): void {
this.hasSrc = false;
this.hasIcon = false;
this.hasText = false;
if (this.nzIcon) {
this.hasIcon = true;
} else if (this.nzText) {
this.hasText = true;
imgError($event: Event): void {
this.nzError.emit($event);
if (!$event.defaultPrevented) {
this.hasSrc = false;
this.hasIcon = false;
this.hasText = false;
if (this.nzIcon) {
this.hasIcon = true;
} else if (this.nzText) {
this.hasText = true;
}
this.setClass().notifyCalc();
this.setSizeStyle();
}
this.setClass().notifyCalc();
this.setSizeStyle();
}

ngOnChanges(changes: SimpleChanges): void {
Expand Down