.Net Core 中的微调器 Angular 5 打字稿

spinner in .Net Core Angular 5 typescript

我试图在 .Net Core 2 / Angular 5.Angular 中实现此处定义的打字稿微调器 component/service ( How to do loading spinners, the Angular 2+ way )。

当包含微调器标签的页面加载时:

<spinner name="skuLoadSpinner" [(show)]="showSpinner"></spinner>

我收到以下错误:

Uncaught Error: Template parse errors:
Can't bind to 'show' since it isn't a known property of 'spinner'. ("ft;width:50%;">
          <label for="power">SKU</label>
          <spinner name="skuLoadSpinner" [ERROR ->][(show)]="showSpinner"></spinner>
          <select style="" class="form-control" id="sku"
        "): ng:///AppModule/SkuRegistrationComponent.html@125:41
'spinner' is not a known element:
1. If 'spinner' is an Angular component, then verify that it is part of this module.
2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

这是我现在的 spinner.service.ts:

import { Injectable } from '@angular/core';
import { SpinnerComponent } from './spinner.component';

@Injectable()
export class SpinnerService {
  private spinnerCache = new Set<SpinnerComponent>();

  _register(spinner: SpinnerComponent): void {
    this.spinnerCache.add(spinner);
  }

  show(spinnerName: string): void {
    this.spinnerCache.forEach(spinner => {
      if (spinner.name === spinnerName) {
        spinner.show = true;
      }
    });
  }

  hide(spinnerName: string): void {
    this.spinnerCache.forEach(spinner => {
      if (spinner.name === spinnerName) {
        spinner.show = false;
      }
    });
  }

  showGroup(spinnerGroup: string): void {
    this.spinnerCache.forEach(spinner => {
      if (spinner.group === spinnerGroup) {
        spinner.show = true;
      }
    });
  }

  hideGroup(spinnerGroup: string): void {
    this.spinnerCache.forEach(spinner => {
      if (spinner.group === spinnerGroup) {
        spinner.show = false;
      }
    });
  }

  showAll(): void {
    this.spinnerCache.forEach(spinner => spinner.show = true);
  }

  hideAll(): void {
    this.spinnerCache.forEach(spinner => spinner.show = false);
  }

  _unregister(spinnerToRemove: SpinnerComponent): void {
    this.spinnerCache.forEach(spinner => {
      if (spinner === spinnerToRemove) {
        this.spinnerCache.delete(spinner);
      }
    });
  }
}

这是我的 spinner.component.ts 文件:

import { Component, Input, OnInit, EventEmitter, Output, OnDestroy } from '@angular/core';
import { SpinnerService } from './spinner.service';

@Component({
  selector: 'spinner',
  template: `
    <div *ngIf="show">
      <img *ngIf="loadingImage" [src]="loadingImage" />
      <ng-content></ng-content>
    </div>
  `
})
export class SpinnerComponent implements OnInit, OnDestroy {
  @Input() name: string;
  @Input() group: string;
  @Input() loadingImage: string;
  @Input() show = false;

  constructor(private spinnerService: SpinnerService) { }

  ngOnInit(): void {
    if (!this.loadingImage) throw new Error("Spinner must have a loadingImage supplied.");

    this.spinnerService._register(this);
  }

  private isShowing = false;

  @Input()
  get show(): boolean {
    return this.isShowing;
  }

  @Output() showChange = new EventEmitter();

  set show(val: boolean) {
    this.isShowing = val;
    this.showChange.emit(this.isShowing);
  }

  ngOnDestroy(): void {
    this.spinnerService._unregister(this);
  }
}  

我建议将 Input() 装饰器放在 'setter' 而不是 'getter' 上。虽然两者都是有效的,但将其放在 getter 上意味着如果您(出于某种原因)对 [=44] 使用不同的名称,您 可能 运行 会遇到问题=].

我建议更改为:

  get show(): boolean {
    return this.isShowing;
  }

  @Input()
  set show(val: boolean) {
    this.isShowing = val;
    this.showChange.emit(this.isShowing);
  }

此外,删除 show 字段,因为自从您将 isShowing 添加为字段后,它甚至从未被设置过。

编辑 1:

您还需要确保已在 Module 中导入并声明微调器组件。转到您正在工作的 Module(如果您尚未创建共享的,则很可能 AppModule)。

在顶部添加导入语句,然后也在 Moduledeclarations 数组中添加导入语句。

编辑 2:

正如@littleGreenDude 指出的那样,也在那里添加 SpinnerService 的导入语句,但将其放在 providers 数组而不是 declarations 数组中。这会将服务注册到 Angular DI(依赖注入)容器,以便它知道初始化它,以便其他组件可以将它注入到它们中。