0

我创建了一个属性指令ImageSpinloaderDirective来有条件地更改用户个人资料图片的外观,具体取决于是否有图片以及是否已加载:

  • 如果src无法解析属性的 URL(404 等),则应显示默认图像
  • 如果图片仍在加载,则应显示加载动画
  • 如果用户已更改,则会加载新的个人资料图像,并且旋转加载器应再次出现,直到加载完成

我的方法是监听 DOM 事件loaderror在其中相应ImageSpinloaderDirective地设置元素的src属性和img-loading类。<img>该类img-loading将图像不透明度设置为 0,并使用动画 gif 作为背景图像。

现在我想在每次显示不同的用户时isLoading从父组件 ( ) 更改指令的字段。UserDetailsComponent我认为@ViewChild在该组件中使用注释将是实现这一目标的正确选择。然而,由于某种原因,绑定似乎失败了,因为UserDetailsComponent'simageSpinloaderDirective总是未定义的。

是否可以在@ViewChild注释中使用属性指令?有没有更好/替代方法将属性指令绑定到组件?还是这种方法完全错误,应该以不同的方式实施?

用户详细信息.component.ts

Component({
    moduleId: module.id,
    selector: 'user-details',
    templateUrl: 'user-details.html',
    styleUrls: [
        './../grid/grid-item-details.css',
        './../grid/grid.css'
    ],
    animations: [fadeInOut]
})
export class UserDetailsComponent extends GridItemDetailsComponent<User>
{
    public user: User;
    public profileImageUrl: string;

    @ViewChild(ImageSpinloaderDirective)
    public imageSpinloaderDirective: ImageSpinloaderDirective;

    public loadDetails(item: User): void
    {
        this.user = item;
        this.imageSpinloaderDirective.isLoading = true;
        this.profileImageUrl = `${this.configService.config.profileApiUrl}/image/${item.id}`;
    }
}

用户详细信息.html

<div class="row">
  <div class="col-lg-12">
    <div class="img-loader">
      <img id="foo" imgspinloader
           class="img-rounded"
           src="{{profileImageUrl}}">
    </div>
  </div>
</div>

image-spinloader.directive.ts

import
{
    AfterContentChecked,
    Directive,
    HostBinding,
    HostListener,
    Input,
    OnInit
} from '@angular/core';

@Directive({
    selector: '[imgspinloader]'
})
export class ImageSpinloaderDirective
{
    private defaultSrc: string = "assets/img/user-image-invitation-2x.png";

    @Input() @HostBinding() src;

    @Input() @HostBinding("class.img-loading") isLoading: boolean;

    @HostListener('load') complete()
    {
        this.isLoading = false;
    }

    @HostListener('error') onError()
    {
        this.src = this.defaultSrc;
        this.isLoading = false;
    }
}
4

0 回答 0