Angular2滚动到具有* ngIf的元素 [英] Angular2 scroll to element that has *ngIf

查看:81
本文介绍了Angular2滚动到具有* ngIf的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Angular 2中编写一个表单,在该表单中用户提交了表单,表单已经过验证,并且如果输入内容有任何错误,我想将用户的浏览器滚动到类为错误"的第一个元素

问题是,我所有的错误都使用* ngIf

<input type="text" [(ngModel)]="model.first_name">
<div class="error" *ngIf="errors.first_name">
    {{errors.first_name}}
</div>

在我的提交功能中

submit(){
   this.errors = this.validate();
   if(this.errors.any()){
      var errorDivs = document.getElementsByClassName("error");
      if(errorDivs.length > 0){
         errorDivs[0].scrollIntoView();
      }
   }
}

我意识到这是因为* ngIf完全从DOM中删除了div,并且尚未对Angular进行更改检查.有聪明而干净的方法可以做到这一点吗?

解决方案

这是我想出的一种方法:

创建一个帮助器类

export class ScrollHelper {
    private classToScrollTo: string = null;

    scrollToFirst(className: string) {
        this.classToScrollTo = className;
    }

    doScroll() {
        if (!this.classToScrollTo) {
            return;
        }
        try {
            var elements = document.getElementsByClassName(this.classToScrollTo);
            if (elements.length == 0) {
                return;
            }
            elements[0].scrollIntoView();
        }
        finally{
            this.classToScrollTo = null;
        }
    }
}

然后在您希望在其中使用的组件中创建一个

private scrollHelper : ScrollHelper = new ScrollHelper();

然后,当您发现自己有错误

submit(){
   this.errors = this.validate();
   if(this.errors.any()){
        this.scrollHelper.scrollToFirst("error");
   }
}

然后将实际滚动推迟到评估*ngIf后的ngAfterViewChecked

ngAfterViewChecked(){
    this.scrollHelper.doScroll();
}

I am writing a form in Angular 2 where the user submits the form, it is validated and if there are any errors with the inputs, I want to scroll the user's browser to the first element with the class "error"

The problem is, all of my errors use *ngIf like so:

<input type="text" [(ngModel)]="model.first_name">
<div class="error" *ngIf="errors.first_name">
    {{errors.first_name}}
</div>

In my submit function

submit(){
   this.errors = this.validate();
   if(this.errors.any()){
      var errorDivs = document.getElementsByClassName("error");
      if(errorDivs.length > 0){
         errorDivs[0].scrollIntoView();
      }
   }
}

I realize this is because *ngIf removes the div from the DOM completely and the Angular check for changes hasn't been given a chance to run yet. Is there a clever and clean way to do this?

解决方案

Here's a way I figured out:

Create a helper class

export class ScrollHelper {
    private classToScrollTo: string = null;

    scrollToFirst(className: string) {
        this.classToScrollTo = className;
    }

    doScroll() {
        if (!this.classToScrollTo) {
            return;
        }
        try {
            var elements = document.getElementsByClassName(this.classToScrollTo);
            if (elements.length == 0) {
                return;
            }
            elements[0].scrollIntoView();
        }
        finally{
            this.classToScrollTo = null;
        }
    }
}

Then create one in the component you wish to use it in

private scrollHelper : ScrollHelper = new ScrollHelper();

then when you find out you have errors

submit(){
   this.errors = this.validate();
   if(this.errors.any()){
        this.scrollHelper.scrollToFirst("error");
   }
}

then postpone the actual scroll until ngAfterViewChecked after *ngIf has been evaluated

ngAfterViewChecked(){
    this.scrollHelper.doScroll();
}

这篇关于Angular2滚动到具有* ngIf的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆