Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 获取所有ngfor元素的参考并显示其各自的当前位置_Angular - Fatal编程技术网

Angular 获取所有ngfor元素的参考并显示其各自的当前位置

Angular 获取所有ngfor元素的参考并显示其各自的当前位置,angular,Angular,我想获得对每个ngFor元素的引用,并在其中显示最新的顶部和左侧位置。这些元素可以被拖动,这就是为什么位置会发生变化的原因 我可以为单个元素获取一个值,但wrt to ngFor elements和那里的最新值,所以当我尝试在ngAfterViewChecked中访问它时,我得到的Querylist为空 <div *ngFor="let item of list"> {{item.text}} {{ topPos }} </div> @ViewChildren(

我想获得对每个ngFor元素的引用,并在其中显示最新的顶部和左侧位置。这些元素可以被拖动,这就是为什么位置会发生变化的原因

我可以为单个元素获取一个值,但wrt to ngFor elements和那里的最新值,所以当我尝试在ngAfterViewChecked中访问它时,我得到的Querylist为空

<div *ngFor="let item of list">
  {{item.text}}
  {{ topPos }}
</div>

@ViewChildren('elm') elm: QueryList<ElementRef>;

ngAfterViewChecked(){

  // for single
  let elempos = document.getElementById('toget').getBoundingClientRect();
  console.log(elempos.top);
  topPos = elempos.top;

  //for ngfor elements
   console.log(this.elm.toArray());
}
我想你可以用event。因为ngOnChanges触发了所有的变化

ngOnChanges(){
   //Whatever you want
   this.list = .... ; 
   console.log(this.elm.toArray());
} 

您的列表索引将与queryList索引相同,因此您应该能够做到这一点。这利用了QueryList上可观察的更改。每次更新DOM时,都会更新:

模板

组成部分


尽量少用ngOnChanges钩。如果您没有正确使用它,它可能会被调用过多,并将导致性能不佳。几乎所有情况下,你都可以用另一种比ngOnChanges更具描述性的方式来解决

好的ngOnChanges不仅适用于@input,而且适用于每一个更改。如果可能的话,这是你的建议,请详细说明我如何访问每个元素并在其中显示相应的位置,谢谢我猜ngonchanges会有帮助,但是你能帮我看看如何显示双向绑定的每个IndexSangular参数的值吗。所以,只写您想要的元素。最新的值是什么?抱歉,我仍然无法理解如何在每个分区上显示其各自的顶部或左侧位置,请详细说明,我会尝试,如果它有效,我可以接受,因为这是部分答案,ngonchanges有效,但我如何显示它我添加了控制台屏幕截图,我通过console.logthis.elm.toArray,现在,如何获取每个元素的值和显示您不能订阅DOM元素的位置更改。相反,您应该监听拖放事件并处理更改。@Reactgular ok我可以这样做吗[style.position.left]=item.position并获取元素的当前位置并绑定它我在指令@HostListener'dragMove',['$event']OndFragmoveEvent:PointerEvent中有hostlistner{this.position.x=event.clientX-this.startPosition.x;this.position.y=event.clientY-this.startPosition.y;}@Reactgular,但在为this.elm.toArray执行ngonchanges内的console时,会给我值,但我不知道要选择哪一个,我希望左侧和顶部位置wrt到父容器,我会添加屏幕快照,您在哪里设置,列表?非常感谢,我会尝试一下,所以这会给我窗口文档的x和y位置wrt如果我没有错,它会如果你能就如何将x和y位置wrt提交给直系家长提出建议,那就太好了container@Enthu我已经更新了我的答案。您必须在元素本身上使用offsetTop和offsetLeft。更好的做法是为此使用自定义指令,然后使用HostListener从那里设置值,然后让您r ViewChildren对该指令进行查询,而不是使用NativeElementThankyu,我添加了用于计算位置的自定义指令代码,如何将该wrt用于特定元素和显示,而且我还不清楚位置是指向父项还是指向窗口,Thankhi,它给出了me an error=error error:expressionChangedTerithasBeenCheckedError:Expression在检查后已更改。以前的值:“ngForOf:null”。当前值:“ngForOf:”。啊,是的,因为我们在NafterViewInit内设置了observable,所以需要执行detectChanges,或者将组件设置为OnPush并设置为markForCheck
ngOnChanges(){
   //Whatever you want
   this.list = .... ; 
   console.log(this.elm.toArray());
} 
<div *ngFor="let itemPos of itemPositions$ | async;trackBy:trackByItem">
  {{ itemPos.item?.text }}
  {{ itemPos.element?.offsetTop }}
  {{ itemPos.element?.offsetLeft}}
</div>
@Input()
list: any[] = [];

@ViewChildren('elm') 
elm?: QueryList<ElementRef<HTMLElement>>;

itemPositions$?: Observable<{ item: any, element: HTMLElement}[]>;

constructor(readonly cd: ChangeDetectorRef) {}

ngAfterViewInit(){
  this.itemPositions$ = this.elm.changes.pipe(
    map(() => this.elementsToPositions()),
    tap(() => this.cd.detectChanges()),
    startWith(this.elementsToPositions()),
    shareReplay(1)
  );

  this.cd.detectChanges();
}

elementsToPositions(): { item: any, element: HTMLElement}[] {
  return this.elm.toArray().map(({ nativeElement }, i) => ({
    item: this.list[i],
    element: nativeElement
  });
}

trackByItem = (i: number, itemPos: { item: any, element: HTMLElement}): string | number {
  // make sure every item has some unique ID, otherwise the `changes` will get 
  // called too often
  return itemPos.item.id || i;
}