与 DOM 解耦并将功能引入指令

Decoupling from the DOM and bringing functionality into a directive

我正在尝试制定 Snap-to-Component 指令。在这一点上,我已经用应用程序组件中的逻辑进行了概念验证(可能会被 Renderer2 HostListeners 和 HostBindings 取代),看起来我必须获得 dom 属性(child1L,child1R...等)的 children 可能使用 Renderer2。我的问题是,您如何将我到目前为止所做的事情分离到一个指令或一组 parent 和 child 指令中?或者至少你会从这里往哪个方向走?我不熟悉使用 Renderer2、HostListeners 和 HostBinding,所以我想知道更有经验的人会如何做到这一点。谢谢你。这是我的 current stackblitz.

app.component.ts:

import { Component,ElementRef,ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

switchDirection = "first";
head: ElementRef;

@ViewChild('child01') child01;
@ViewChild('child02') child02;
@ViewChild('child03') child03;

  onScroll(event: Event) {
    let viewBoundaryL = (event.target as HTMLElement).scrollLeft;
    console.log("viewBoundaryL:" + viewBoundaryL);

//SNAP FROM FIRST TO SECOND CHILD
    if(viewBoundaryL >= 50 && this.switchDirection === "first"){
this.child02.el.nativeElement.scrollIntoView({ behavior: 'smooth', block: "center"  });
setTimeout(() => {
     this.switchDirection = "second";
      //  console.log(this.switchDirection)
    }, 300);
    }

//SNAP FROM SECOND TO FIRST CHILD
    if(viewBoundaryL <= 310 && this.switchDirection === "second"){
this.child01.el.nativeElement.scrollIntoView({ behavior: 'smooth', block: "center"  });
setTimeout(() => {
  this.switchDirection = "first";
  // console.log(this.switchDirection)
    }, 300);
    }

//SNAP FROM SECOND TO THIRD CHILD
        if(viewBoundaryL >= 370 && this.switchDirection === "second"){
this.child03.el.nativeElement.scrollIntoView({ behavior: 'smooth', block: "center"  });
setTimeout(() => {
  this.switchDirection = "third";
  // console.log(this.switchDirection)
    }, 300);
  }

//SNAP FROM THIRD TO SECOND CHILD
        if(viewBoundaryL <= 615 && this.switchDirection === "third"){
this.child02.el.nativeElement.scrollIntoView({ behavior: 'smooth', block: "center"  });
setTimeout(() => {
  this.switchDirection = "second";
  // console.log(this.switchDirection)
    }, 300);
        }     
  }
}

app.component.html:

 <div class="container"  (scroll)="onScroll($event)" >

<child1 #child01></child1>
<child2 #child02></child2>
<child3 #child03></child3>

</div>

感谢您的见解!

您可能想要创建一个 attribute directive

您可以使用 Angular CLI 和以下命令轻松创建 directive(您可以提供路径作为名称 core/directives/my-directive-name):

ng generate directive <name-of-directive>

然后在构造函数中,您可以添加以下内容以获取对元素的引用。

el: ElementRef

最后使用 HostListener 或任何技术绑定到滚动事件。您可以调用您的 snap to element 代码(必须更改为仅检查自身),然后该元素将检查自己是否需要启动滚动。如果它满足条件,那么它就满足。

为了进一步加分,您可以添加设置输入和捕捉元素的时间,例如,带有指令的模板将如下所示:

<div [myDirective] [scrollAt]="300"></div>

然后在指令本身中你将拥有:

@Input() scrollAt: number = 300 // sets a default incase it isn't provided;

然后您可以将此变量用于您的视图边界。

希望这对您有所帮助,或者至少让您走上正轨!