Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.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 7(SmartAdmin模板)表单验证在导航后停止工作_Angular_Angular7_Angular Reactive Forms_Smartadmin_Angular2 Form Validation - Fatal编程技术网

如何修复:Angular 7(SmartAdmin模板)表单验证在导航后停止工作

如何修复:Angular 7(SmartAdmin模板)表单验证在导航后停止工作,angular,angular7,angular-reactive-forms,smartadmin,angular2-form-validation,Angular,Angular7,Angular Reactive Forms,Smartadmin,Angular2 Form Validation,我正在尝试在angular 7应用程序上执行表单验证,该应用程序使用智能管理模板(wrapbootstrap中的主题) 我的问题是,它在浏览器第一次刷新时,甚至在我导航到不包含其他表单的组件时,都能正常工作。 当我导航到一个组件时,会出现这个问题,该组件还包括一个具有自身验证选项的表单 此外,表单的实际“有效性”状态仍按预期工作。它只是没有在表单上显示引导类和消息 我尝试过重置表单,重置任何异步/非异步验证器以及我能想到的任何其他东西 最后,在组件之间的导航过程中没有错误或任何东西 这是我处理导

我正在尝试在angular 7应用程序上执行表单验证,该应用程序使用智能管理模板(wrapbootstrap中的主题)

我的问题是,它在浏览器第一次刷新时,甚至在我导航到不包含其他表单的组件时,都能正常工作。 当我导航到一个组件时,会出现这个问题,该组件还包括一个具有自身验证选项的表单

此外,表单的实际“有效性”状态仍按预期工作。它只是没有在表单上显示引导类和消息

我尝试过重置表单,重置任何异步/非异步验证器以及我能想到的任何其他东西

最后,在组件之间的导航过程中没有错误或任何东西

这是我处理导航的主要模块(main.routing.ts):

这是一个表单示例(create team.component.html):

编辑:为了提供更多信息,以下是SmartAdmin模板使用的自定义验证:

import { Directive, Input, ElementRef } from "@angular/core";

@Directive({
  selector: "[saUiValidate]"
})
export class UiValidateDirective {
  @Input() saUiValidate: any;

  constructor(private el: ElementRef) {
    Promise.all([
      import("jquery-validation/dist/jquery.validate.js"),
      import("jquery-validation/dist/additional-methods.js")
    ])
    .then(() => {
      this.attach();
    });
  }

  attach() {
    const $form = $(this.el.nativeElement);
    const validateCommonOptions = {
      rules: {},
      messages: {},
      errorElement: "em",
      errorClass: "invalid",
      highlight: (element, errorClass, validClass) => {
        $(element)
          .addClass(errorClass)
          .removeClass(validClass);
        $(element)
          .parent()
          .addClass("state-error")
          .removeClass("state-success");
      },
      unhighlight: (element, errorClass, validClass) => {
        $(element)
          .removeClass(errorClass)
          .addClass(validClass);
        $(element)
          .parent()
          .removeClass("state-error")
          .addClass("state-success");
      },

      errorPlacement: (error, element) => {
        if (element.parent(".input-group").length) {
          error.insertAfter(element.parent());
        } else {
          error.insertAfter(element);
        }
      }
    };

    $form
      .find("[data-smart-validate-input], [smart-validate-input]")
      .each(function() {
        var $input = $(this),
          fieldName = $input.attr("name");

        validateCommonOptions.rules[fieldName] = {};

        if ($input.data("required") != undefined) {
          validateCommonOptions.rules[fieldName].required = true;
        }
        if ($input.data("email") != undefined) {
          validateCommonOptions.rules[fieldName].email = true;
        }

        if ($input.data("maxlength") != undefined) {
          validateCommonOptions.rules[fieldName].maxlength = $input.data(
            "maxlength"
          );
        }

        if ($input.data("minlength") != undefined) {
          validateCommonOptions.rules[fieldName].minlength = $input.data(
            "minlength"
          );
        }

        if ($input.data("message")) {
          validateCommonOptions.messages[fieldName] = $input.data("message");
        } else {
          Object.keys($input.data()).forEach(key => {
            if (key.search(/message/) == 0) {
              if (!validateCommonOptions.messages[fieldName])
                validateCommonOptions.messages[fieldName] = {};

              var messageKey = key.toLowerCase().replace(/^message/, "");
              validateCommonOptions.messages[fieldName][
                messageKey
              ] = $input.data(key);
            }
          });
        }
      });

    $form.validate($.extend(validateCommonOptions, this.saUiValidate));
  }
}

编辑2:我已经设法找到了解决这个问题的办法,尽管我有点不喜欢。似乎在调用自定义UI验证时,组件尚未呈现(我猜这与异步运行有关)。 解决方案是在验证组件中添加0毫秒的“设置超时”,如下所示:

  constructor(private el: ElementRef) {
    Promise.all([
      import("jquery-validation/dist/jquery.validate.js"),
      import("jquery-validation/dist/additional-methods.js")
    ])
      .then(() => {
        setTimeout(_ => {
          this.attach();
        }, 0);
      });
  }
如果有人能想出更好的解决方案,我们将不胜感激:)


期待听到你的想法。

因此,我遇到了与你相同的问题,也尝试了你的方法。虽然它确实可以工作,但请注意,通过将逻辑移动到ngOnInit()方法(无需修改),它也可以工作。我相信这与ngOnInit在调用组件之前等待组件完全呈现和初始化有关,这反过来确保绑定可用

下面是我用来让它工作的相关代码(attach()方法之前的所有内容)。这在ui-validate.directive.ts中:

import { Directive, Input, ElementRef, OnInit } from "@angular/core";

@Directive({
  selector: "[saUiValidate]"
})
export class UiValidateDirective implements OnInit {
  @Input() saUiValidate: any;

  constructor(private el: ElementRef) { }

  ngOnInit(){
    Promise.all([
      import("jquery-validation/dist/jquery.validate.js"),
      import("jquery-validation/dist/additional-methods.js")
    ])
    .then(() => {
      this.attach();
    });
  }
import { Directive, Input, ElementRef } from "@angular/core";

@Directive({
  selector: "[saUiValidate]"
})
export class UiValidateDirective {
  @Input() saUiValidate: any;

  constructor(private el: ElementRef) {
    Promise.all([
      import("jquery-validation/dist/jquery.validate.js"),
      import("jquery-validation/dist/additional-methods.js")
    ])
    .then(() => {
      this.attach();
    });
  }

  attach() {
    const $form = $(this.el.nativeElement);
    const validateCommonOptions = {
      rules: {},
      messages: {},
      errorElement: "em",
      errorClass: "invalid",
      highlight: (element, errorClass, validClass) => {
        $(element)
          .addClass(errorClass)
          .removeClass(validClass);
        $(element)
          .parent()
          .addClass("state-error")
          .removeClass("state-success");
      },
      unhighlight: (element, errorClass, validClass) => {
        $(element)
          .removeClass(errorClass)
          .addClass(validClass);
        $(element)
          .parent()
          .removeClass("state-error")
          .addClass("state-success");
      },

      errorPlacement: (error, element) => {
        if (element.parent(".input-group").length) {
          error.insertAfter(element.parent());
        } else {
          error.insertAfter(element);
        }
      }
    };

    $form
      .find("[data-smart-validate-input], [smart-validate-input]")
      .each(function() {
        var $input = $(this),
          fieldName = $input.attr("name");

        validateCommonOptions.rules[fieldName] = {};

        if ($input.data("required") != undefined) {
          validateCommonOptions.rules[fieldName].required = true;
        }
        if ($input.data("email") != undefined) {
          validateCommonOptions.rules[fieldName].email = true;
        }

        if ($input.data("maxlength") != undefined) {
          validateCommonOptions.rules[fieldName].maxlength = $input.data(
            "maxlength"
          );
        }

        if ($input.data("minlength") != undefined) {
          validateCommonOptions.rules[fieldName].minlength = $input.data(
            "minlength"
          );
        }

        if ($input.data("message")) {
          validateCommonOptions.messages[fieldName] = $input.data("message");
        } else {
          Object.keys($input.data()).forEach(key => {
            if (key.search(/message/) == 0) {
              if (!validateCommonOptions.messages[fieldName])
                validateCommonOptions.messages[fieldName] = {};

              var messageKey = key.toLowerCase().replace(/^message/, "");
              validateCommonOptions.messages[fieldName][
                messageKey
              ] = $input.data(key);
            }
          });
        }
      });

    $form.validate($.extend(validateCommonOptions, this.saUiValidate));
  }
}

  constructor(private el: ElementRef) {
    Promise.all([
      import("jquery-validation/dist/jquery.validate.js"),
      import("jquery-validation/dist/additional-methods.js")
    ])
      .then(() => {
        setTimeout(_ => {
          this.attach();
        }, 0);
      });
  }
import { Directive, Input, ElementRef, OnInit } from "@angular/core";

@Directive({
  selector: "[saUiValidate]"
})
export class UiValidateDirective implements OnInit {
  @Input() saUiValidate: any;

  constructor(private el: ElementRef) { }

  ngOnInit(){
    Promise.all([
      import("jquery-validation/dist/jquery.validate.js"),
      import("jquery-validation/dist/additional-methods.js")
    ])
    .then(() => {
      this.attach();
    });
  }