我有一个名为app.component的组件,它是angular项目中的主要组件。到客户组件的导航是通过路由完成的。和
文件夹结构src app
- app.component.html
- app.component.ts
和src app 客户组件
- customer.component.html
- customer.component.ts
在我的app.component.html中
<div class="top-container" #topContainerRef>
<router-outlet></router-outlet>
</div>
在我的customer.component.ts
我想获得引用的最顶部的容器div包含在app.components
我想替换
document.getElementsByClassName('top-container')[0].scrollTop = some values
与
相似@ViewChild('topContainerRef', { read: ElementRef, static: false }) topContainerRef: ElementRef;
this.topContainerRef.nativeElement.scrollTop= "some value" //here the topContainerRef is undefined
是否可以使用elementRef来代替classname或Id ?
您不能使用ViewChild
的#topContainerRef
来获得此元素的引用,因为它不是由您的CustomerComponent
呈现的。
你要么需要在应用组件内部获取这个元素的引用,然后想办法把它传递给所有可能需要它的子元素(不推荐)。
或者你可以构建一个服务,然后使用它来"请求";scrollTop会被任何访问该元素的组件(在你的例子中是app组件)所改变。
我会这样做:
export class AppContainerService {
private scrollTopSource = new ReplaySubject<number>(1);
public scrollTop$ = this.scrollTopSource.asObservable();
public updateScrollTop(value: number) {
this.scrollTopSource.next(value);
}
}
Inside yourCustomerComponent
:
public class CustomerComponent implements OnInit {
// ...
constructor(private containerService: AppContainerService) {
}
ngOnInit() {
this.containerService.updateScrollTop(/* whatever value you need */);
}
// ...
}
最后,AppComponent会对scrollTop的改变做出反应:
export class AppComponent implements AfterViewInit {
@ViewChild('topContainerRef', { read: ElementRef, static: false }) topContainerRef: ElementRef;
private subscriptions = new Subscription();
constructor(private containerService: AppContainerService) {
}
ngAfterViewInit() {
this.subscriptions.add(this.containerService.scrollTop$.subscribe((value: number) => {
this.topContainerRef.nativeElement.scrollTop = value;
}));
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
}
不要忘记在ngOnDestroy
内取消订阅。这很重要,这样你就不会有内存泄漏