将Angularjs弹出窗口迁移到Angular 14

liwlm1x9  于 2023-01-25  发布在  Angular
关注(0)|答案(1)|浏览(154)

我正在将我的Web应用程序从AngularJS 1.5.3迁移到Angular 14.2,在我的应用程序中使用了弹出窗口模板,请参见下文
超文本标记语言

<a id="{{mapObj.stId}}" popover-template="'{{mapObj.statusTemplate}}'"
popover-trigger="outsideClick" popover-classes="editable-container editable-popup"
popover-title="{{mapObj.statusTitle}}" ng-click="onStatusClick(mapObj)"
class="editable editable-click" style="color: rgb(128, 128, 128);cursor:pointer"
 tabindex="0">
<span><b>Accept, Decline, or Reduce total </b></span>

</a>

   <script type="text/ng-template" id="{{mapObj.stId}}status.html">   
       <div>
          <form class="form-inline editableform">
              <div class="control-group form-group">
              .....
              .....
              </div>
            </form>
        </div>
   </script>

Controller.js

onStatusClick= function (mapObj) {
                if (!mapObj.isHidePopover) {
                    mapObj.statusTemplate = mapObj.stId + "status.html";

                    
                    mapObj.statusTitle = "Accept, Decline, or Request Reduction";
                    
                }
                mapObj.isHidePopover = false;
            };

我需要帮助在不使用任何第三方的情况下在Angular 14.2中编写相同的代码(我使用的是带angular的 Bootstrap ,这很好)。对此有什么建议/帮助吗?

qoefvg9y

qoefvg9y1#

Angular 2+(或者14.2在你的情况下)是完全不同的Angular JS。所以一个简单的转换可能是非常困难的,正如你一定注意到的。有一些库可以帮助你创建一个弹出非常容易,比如Bootstrap(ng-bootstrap)。但是如果你想用pureAngular 2的方法来学习它是如何工作的,那么就在这里!(Stackblitz
我认为对于弹出窗口来说,Angular Directive是一个不错的选择。Directive可以操纵它的主机组件的外观或行为。阅读所有关于here的内容。

  • 下面的Directive执行以下操作:OnInit加载ng-template并将其显示在其父对象的底部。一些点击侦听器处理背景点击和/或弹出状态本身。*
@Directive({
  selector: "[popoverTrigger]"
})
export class PopoverDirective implements OnDestroy, OnInit {
  @Input()
  popoverTrigger!: TemplateRef<object>;

  @Input()
  closeOnClickOutside: boolean = false;

  private unsubscribe = new Subject();
  private overlayRef!: OverlayRef;

  constructor(
    private elementRef: ElementRef,
    private overlay: Overlay,
    private vcr: ViewContainerRef,
    private popoverService: PopoverService
  ) {}

  ngOnInit(): void {
    this.createOverlay();
    this.popoverService.getState().subscribe(resp => {
      if (resp) {
        this.detachOverlay();
      }
    });
  }

  ngOnDestroy(): void {
    this.detachOverlay();
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }

  @HostListener("click") clickou() {
    this.attachOverlay();
  }

  private createOverlay(): void {
    const scrollStrategy = this.overlay.scrollStrategies.block();
    const positionStrategy = this.overlay.position().connectedTo(
      this.elementRef,
      { originX: "start", originY: "bottom" },
      { overlayX: "start", overlayY: "top" }

      //ToDo entender como funciona o posicionamento
      // new ConnectionPositionPair(
      //   { originX: "start", originY: "bottom" },
      //   { overlayX: "start", overlayY: "bottom" }
      // ),
      // new ConnectionPositionPair(
      //   { originX: "start", originY: "bottom" },
      //   { overlayX: "start", overlayY: "bottom" }
      // )
    );

    this.overlayRef = this.overlay.create({
      positionStrategy,
      scrollStrategy,
      hasBackdrop: true,
      backdropClass: ""
    });

    this.overlayRef
      .backdropClick()
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(() => {
        if (this.closeOnClickOutside) {
          this.detachOverlay();
        }
      });
  }

  private attachOverlay(): void {
    if (!this.overlayRef.hasAttached()) {
      const periodSelectorPortal = new TemplatePortal(
        this.popoverTrigger,
        this.vcr
      );

      this.overlayRef.attach(periodSelectorPortal);
    }
  }

  private detachOverlay(): void {
    if (this.overlayRef.hasAttached()) {
      this.overlayRef.detach();
    }
  }
}

所以...很多代码。但是只写一次,并用于所有你想要的组件。现在在你的组件中,比如app.component.ts,你需要在html中设置如下内容:

<p [popoverTrigger]="popoverVazio">
  Popover no texto
</p>

<ng-template #popoverVazio>
  <popover-container>
    <p>exemplo de popovere acionado por um texto</p>
    <button mat-raised-button color="primary" (click)="closePopover()">
      Fechar
    </button>
  </popover-container>
</ng-template>

就是这样。ng-template没有显示。只有当弹出窗口打开时才显示。顺便说一下,默认情况下,ng-template也总是不显示。如果你设置了ngIf="true"(作为示例),那么它将是可见的。更多关于它的信息here

相关问题