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

Angular:如何使用与cdkConnectedOverly的指令微同步?

  •  1
  • checketts  · 技术社区  · 6 年前

    Angular docs ,有一个可以与结构指令一起使用的微语法。

    所以我有一些代码 cdkConnectedOverlay 使用“长手”形式时的指令:

      <ng-template 
        cdkConnectedOverlay 
        [cdkConnectedOverlayOrigin]="savedSearchTrigger" 
        [cdkConnectedOverlayOpen]="savedSearchToggle.checked"
        [cdkConnectedOverlayHasBackdrop]="true" 
        [cdkConnectedOverlayBackdropClass]="'transparentOverlayBackdrop'">
        My overlay contents!
      </ng-template>
    

    在阅读了microsyntax之后,我应该能够将代码缩短为:

      <ng-template 
        *cdkConnectedOverlay="origin: savedSearchTrigger; open: savedSearchToggle.checked; hasBackdrop: true; backdropClass: 'transparentOverlayBackdrop'">
         My overlay contents!
      </ng-template>
    

    但是,这不是编译。给了我错误 Cannot read the property 'toUpperCase' of undefined

    我想知道我是否在一个 ng-template 才是罪魁祸首。

    我做错什么了?有工作吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   yurzui    6 年前

    角度编译器希望微同步以值开头

    *cdkConnectedOverlay="cdkConnectedOverlayValue; otherProp: otherPropValue...."
    

    *cdkConnectedOverlay="let x; otherProp: otherPropValue...."
    

    自从 CdkConnectedOverlay @Input 有名字的 CdkConnectedOverlay

    *cdkConnectedOverlay="1;origin: savedSearchTrigger;...
    

    要解决这个问题,可以使用 [cdkConnectedOverlay] 选择器和 属性,但我将使用第一个解决方案:

    <ng-container *cdkConnectedOverlay="let x;origin: savedSearchTrigger; open: opened; 
                     hasBackdrop: true; backdropClass: 'transparentOverlayBackdrop'">
    

    尽管它将编译,但您可以注意到您的内容没有显示。为了修好它你应该用 <ng-container *cdkConnectedOverlay 而不是 <ng-template *cdkConnectedOverlay 以便 My overlay contents! 内容不会被附加包装 ng-template

    Ng-run Example

    更新

    注意,糖 (*) 语法不支持 @Output

    <ng-container *cdkConnectedOverlay="..." (backdropClick)="opened = false">
    

    要解决这个问题,可以通过 通过创建其他指令,例如:

    @Directive({
      selector: '[cdkConnectedOverlayBackdropClick]'
    })
    export class ConnectedOverlayBackdropClick {
      @Input('cdkConnectedOverlayBackdropClick') backDropHandler: Function;
    
      @HostListener('backdropClick')
      backdropClick() {
        this.backDropHandler();
      }
    }
    

    然后在组件中捕获事件:

    组件.html

    <ng-container *cdkConnectedOverlay="let item; origin: savedSearchTrigger; open: opened; 
    hasBackdrop: true; backdropClass: 'transparentOverlayBackdrop'; backdropClick: close">
    

    组件.ts

    close = () => {
      this.opened = false;
    }
    

    Ng-run Example