以编程方式将表单和输入设置为“ng-dirty”

时间:2022-12-05 07:49:39

I've never worked with Angular or Angular2 before, but now I have to make an update to a site running on my domain that is using Angular2. I need to programatically fill out a textbox and click submit, but after setting the textbox's value using .value = "val", it still treats the textbox as if it is empty.

我以前从未使用过Angular或Angular2,但是现在我必须对使用Angular2的域上运行的站点进行更新。我需要以编程方式填写文本框并单击“提交”,但在使用.value =“val”设置文本框的值后,它仍将文本框视为空。

I've read up on angular and now understand the concept of ng-dirty and ng-pristine, but programatically changing the class to ng-dirty still doesn't work.

我已经阅读了有角度的内容,现在理解了ng-dirty和ng-pristine的概念,但是以编程方式将类更改为ng-dirty仍然无法正常工作。

It seems like even if I change the classes, it is still not updating the "pristine" status and it still considers the textbox empty.

似乎即使我更改了类,它仍然没有更新“原始”状态,它仍然认为文本框是空的。

I've read about "markAsDirty()" and tried using it but I get "markAsDirty is not a function". I just need to figure out how to update the page so that it realizes that the textbox is not empty and lets me submit the form.

我读过“markAsDirty()”并尝试使用它,但我得到“markAsDirty不是一个函数”。我只需要弄清楚如何更新页面,以便它意识到文本框不是空的,并让我提交表单。

Thanks a lot!

非常感谢!

Edit: Page form:

编辑:页面形式:

<form id="form_register" novalidate="">
    <div class="form-steps">
        <div class="form-group">
            <div class="input-group">
                <input autocomplete="off" class="form-control ng-pristine ng-invalid ng-touched" data-is-regex="true" data-mask="[a-zA-Z0-1\.]+" id="username" name="username" ngcontrol="username" placeholder="Username" required="" style="color: black !important;" tabindex="13" type="text">
            </div>
        </div>
        <div class="form-group">
            <div class="input-group">
                <input autocomplete="off" class="form-control ng-untouched ng-pristine ng-invalid" id="password" name="password" ngcontrol="password" placeholder="Password" required="" style="color: black !important;" tabindex="14" type="password">
            </div>
        </div>
        <div class="form-group">
            <button class="btn btn-block btn-lg btn-info" tabindex="4" type="submit">
                                   Log In
            </button>
        </div>
    </div>
</form>

My problem is that this:

我的问题是:

document.getElementById("username").value = "testuser";
document.getElementById("password").value = "testpass";
document.getElementsByClassName("btn btn-block btn-lg btn-info")[0].click();

ends up giving me a message saying the username and password are required even though there is a value showing in the textbox. Simply clicking on the textbox, typing a character, then deleting it will allow me to submit the form, but I need to accomplish this without user interaction.

最后给我一条消息,说明即使文本框中显示了值,也需要用户名和密码。只需单击文本框,键入一个字符,然后删除它将允许我提交表单,但我需要在没有用户交互的情况下完成此操作。

2 个解决方案

#1


1  

You are filling the forms with native javascript and that is not updating the angular model. In your backing component you need to use ngmodel to connect your elements to the component. Then update the variables in the component and everything will reflect correctly.

您正在使用本机javascript填充表单,而不是更新角度模型。在后备组件中,您需要使用ngmodel将元素连接到组件。然后更新组件中的变量,一切都会正确反映。

#2


1  

Okay, there are a few issues with your code that I can see and I'll walk through getting this to work as expected.

好的,我可以看到你的代码存在一些问题,我将按照预期的方式使用它。

For a Template driven form, create and assign the form group variable (which will make our shiny NgForm which we later attach controls to with ngControl) in the template, and lets bind the submit function while we're at it:

对于模板驱动的表单,在模板中创建并分配表单组变量(这将使我们后来使用ngControl附加控件的闪亮NgForm),并让我们在它时绑定提交函数:

<form #myForm="ngForm" (ngSubmit)="submit(myForm.value)" id="form_register" novalidate="">

Each of our inputs is standalone and not yet tied to the form, to do so we'll want to clear the ng- classes which should be managed by Angular 2 and add our [(ngModel)] binding to a property.

我们的每个输入都是独立的,但尚未与表单绑定,为此,我们要清除应由Angular 2管理的ng-类,并将[[ngModel]]绑定添加到属性中。

<input autocomplete="off" class="form-control" data-is-regex="true" data-mask="[a-zA-Z0-1\.]+"
                      id="username" name="username" placeholder="Username" ngControl="username" [(ngModel)]="username"
                      required style="color: black !important;" tabindex="13" type="text">

We're going to disable our submit if the form is invalid:

如果表单无效,我们将禁用我们的提交:

<button [disabled]="myForm.invalid" class="btn btn-block btn-lg btn-info" tabindex="4" type="submit">Log In</button>

Our class has the username and password properties that we bind to, and our submit function:

我们的类有我们绑定的用户名和密码属性,以及我们的提交函数:

export class App {
  password: string;
  username: string;

  submit(value) {
     console.log("submitting: " + JSON.stringify(value));
  }
}

Finally, if we really want to mark things dirty programmatically this way we will have to grab our template variable in our code with a ViewChild:

最后,如果我们真的想以编程方式标记脏东西,我们将不得不使用ViewChild在代码中获取模板变量:

@ViewChild('myForm') formGroup;
password: string;

ngAfterContentInit() {
    this.formGroup.control.markAsDirty();
}

To do it per control we either need to access it through our formGroup variable or add individual template variables on the inputs we can grab with [(ngModel)]="username" #username="ngModel", for instance.

要按照控件执行操作,我们需要通过formGroup变量访问它,或者在我们可以使用[(ngModel)] =“username”#username =“ngModel”获取的输入上添加单个模板变量。

here's a plunker you can play with to try and develop your understanding: http://plnkr.co/edit/ukJ1kq2UFBvtoCsxbyba?p=preview

这是一个你可以玩的玩家尝试和发展你的理解:http://plnkr.co/edit/ukJ1kq2UFBvtoCsxbyba?p =preview

#1


1  

You are filling the forms with native javascript and that is not updating the angular model. In your backing component you need to use ngmodel to connect your elements to the component. Then update the variables in the component and everything will reflect correctly.

您正在使用本机javascript填充表单,而不是更新角度模型。在后备组件中,您需要使用ngmodel将元素连接到组件。然后更新组件中的变量,一切都会正确反映。

#2


1  

Okay, there are a few issues with your code that I can see and I'll walk through getting this to work as expected.

好的,我可以看到你的代码存在一些问题,我将按照预期的方式使用它。

For a Template driven form, create and assign the form group variable (which will make our shiny NgForm which we later attach controls to with ngControl) in the template, and lets bind the submit function while we're at it:

对于模板驱动的表单,在模板中创建并分配表单组变量(这将使我们后来使用ngControl附加控件的闪亮NgForm),并让我们在它时绑定提交函数:

<form #myForm="ngForm" (ngSubmit)="submit(myForm.value)" id="form_register" novalidate="">

Each of our inputs is standalone and not yet tied to the form, to do so we'll want to clear the ng- classes which should be managed by Angular 2 and add our [(ngModel)] binding to a property.

我们的每个输入都是独立的,但尚未与表单绑定,为此,我们要清除应由Angular 2管理的ng-类,并将[[ngModel]]绑定添加到属性中。

<input autocomplete="off" class="form-control" data-is-regex="true" data-mask="[a-zA-Z0-1\.]+"
                      id="username" name="username" placeholder="Username" ngControl="username" [(ngModel)]="username"
                      required style="color: black !important;" tabindex="13" type="text">

We're going to disable our submit if the form is invalid:

如果表单无效,我们将禁用我们的提交:

<button [disabled]="myForm.invalid" class="btn btn-block btn-lg btn-info" tabindex="4" type="submit">Log In</button>

Our class has the username and password properties that we bind to, and our submit function:

我们的类有我们绑定的用户名和密码属性,以及我们的提交函数:

export class App {
  password: string;
  username: string;

  submit(value) {
     console.log("submitting: " + JSON.stringify(value));
  }
}

Finally, if we really want to mark things dirty programmatically this way we will have to grab our template variable in our code with a ViewChild:

最后,如果我们真的想以编程方式标记脏东西,我们将不得不使用ViewChild在代码中获取模板变量:

@ViewChild('myForm') formGroup;
password: string;

ngAfterContentInit() {
    this.formGroup.control.markAsDirty();
}

To do it per control we either need to access it through our formGroup variable or add individual template variables on the inputs we can grab with [(ngModel)]="username" #username="ngModel", for instance.

要按照控件执行操作,我们需要通过formGroup变量访问它,或者在我们可以使用[(ngModel)] =“username”#username =“ngModel”获取的输入上添加单个模板变量。

here's a plunker you can play with to try and develop your understanding: http://plnkr.co/edit/ukJ1kq2UFBvtoCsxbyba?p=preview

这是一个你可以玩的玩家尝试和发展你的理解:http://plnkr.co/edit/ukJ1kq2UFBvtoCsxbyba?p =preview