代码之家  ›  专栏  ›  技术社区  ›  Nikita

如何在angular 5中创建启用了“as syntax”的自定义指令?

  •  -1
  • Nikita  · 技术社区  · 8 年前

    ngIf 指令- as syntax https://toddmotto.com/angular-ngif-async-pipe

    在下面的例子中 user$ 是可观察的。

    <div *ngIf="(user$ | async) as user; else loading">
      <user-profile
        [user]="user.profile">
      </user-profile>
      <user-messages
        [user]="user.messages">
      </user-messages>
    </div>
    
    <ng-template #loading>
      Loading stuff...
    </ng-template>
    

    我已经创建了自己的指令,用加载微调器替换元素的内容,并且我希望能够将observable作为输入传递,请参见下面的代码。

    @Directive({ selector: '[appLoadingData]' })
    export class LoadingDataDirective {
      constructor(
        private templateRef: TemplateRef<any>,
        private viewContainerRef: ViewContainerRef,
        private componentFactoryResolver: ComponentFactoryResolver
      ) { }
      @Input()
      set appLoadingData(data: any) {
        if (data != null) {
          if (data.subscribe) {
            this.addLoadingPlaceholder();
            data.subscribe(() => {
              setTimeout(() => this.addView(), 0);
            });
          } else {
            this.addView();
          }
        } else {
          this.addLoadingPlaceholder();
        }
      }
    
      private addView() {
        this.viewContainerRef.clear();
        this.viewContainerRef.createEmbeddedView(this.templateRef);
      }
    
      private addLoadingPlaceholder() {
        this.viewContainerRef.clear();
        const loadingComponentFactory = this.componentFactoryResolver.resolveComponentFactory(LoadingDataComponent);
        this.viewContainerRef.createComponent(loadingComponentFactory);
      }
    }
    

    我想用下一种方法

        <ng-container *ngFor="let chartConfig of chartsConfigs">
          <div class="chart-wrapper"
            *appLoadingData="(chartConfig.chartGroups$ | async) as groups">
            <chart-summary [chartData]="groups"
              [chartOptionsName]="chartConfig.chartType">
            </chart-summary>
          </div>
        </ng-container>
    

    或者理想情况下 *appLoadingData="chartConfig.chartGroups$ as groups"

    *appLoadingData="chartConfig.chartGroups$ | async" [chartData]="chartConfig.chartGroups$ | async" ),在我的装载机被解雇后有一个延迟,我想这是因为 addView() 作为语法 比如ngIf指令。我试着这样使用它: *appLoadingData="(chartConfig.chartGroups$ | async) as groups" groups 总是 undefined .

    如何实施 在自定义指令中?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Nikita    8 年前

    你可以看到他们正在使用 _context 变量。 https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts

    另见@yurzui答案。 How to declare a variable in a template in Angular2

    我的最终结果:

    export class LoadingDataDirective {
      context: any = {};
      constructor(
        private templateRef: TemplateRef<any>,
        private viewContainerRef: ViewContainerRef,
        private componentFactoryResolver: ComponentFactoryResolver
      ) { }
      @Input()
      set appLoadingData(data: any) {
        if (data != null) {
          if (this.isObservable(data)) {
            this.addLoadingPlaceholder();
            const subscription = data.subscribe((observableResult: any) => {
              this.addView(observableResult);
              subscription.unsubscribe();
            });
          } else {
            this.addView(data);
          }
        } else {
          this.addLoadingPlaceholder();
        }
      }
    
      private addView(contextData: any) {
        this.context.$implicit = this.context.appLoadingData = contextData;
        this.viewContainerRef.clear();
        this.viewContainerRef.createEmbeddedView(this.templateRef, this.context);
      }
    
      private addLoadingPlaceholder() {
        this.viewContainerRef.clear();
        const loadingComponentFactory = this.componentFactoryResolver.resolveComponentFactory(LoadingDataComponent);
        this.viewContainerRef.createComponent(loadingComponentFactory);
      }
    
      private isObservable(data: any): boolean {
        return !!data.subscribe;
      }
    }
    

    chartConfig.charGroup$ -是可观察的吗

       <ng-container *ngFor="let chartConfig of chartsConfigs">
          <div class="chart-wrapper"
            *appLoadingData="chartConfig.chartGroups$ as groups">
            <chart-summary [chartData]="groups"
              [chartOptionsName]="chartConfig.chartType">
            </chart-summary>
          </div>
        </ng-container>