Angular.js โดยทางโปรแกรมตั้งค่าฟิลด์ฟอร์มเป็นสกปรก


105

$dirtyฉันกำลังอัปเดตโปรแกรมบางส่วนของเขตข้อมูลในรูปแบบของฉันที่มีค่าและฉันต้องการที่จะตั้งรัฐสนาม ทำสิ่งที่ชอบ:

$scope.myForm.username.$dirty = true; ดูเหมือนจะไม่ได้ผล

มีวิธีการ$setPristineที่ฉันสามารถใช้เพื่อรีเซ็ตสถานะของฟิลด์ แต่ไม่มี$setDirtyวิธีใด?

แล้วเราจะทำสิ่งนี้ได้อย่างไร?

ฉันเห็นโพสต์นี้https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4แต่ดูเหมือนจะหา$setDirtyวิธีไม่ได้ ฉันใช้ Angular เวอร์ชัน 1.1.5


คุณอาจต้องตั้งค่า (ค่าเริ่มต้น) บางอย่าง?
Cherniv

3
วิธีการ $ setDirty มีการบันทึกไว้ที่นี่: docs.angularjs.org/api/ng.directive:form.FormController
David Lin

2
ดูเหมือนว่าจะอยู่ในระดับฟอร์ม ฉันต้องการ$setDirtyระดับสนาม
super9

ไปที่แขนขาที่นี่ แต่วิธีหนึ่งที่เป็นไปได้ แต่ค่อนข้างแฮ็ควิธีแก้ปัญหานี้คือการค้นหาว่าเหตุการณ์ใดที่ผู้ฟังเชิงมุมใช้เพื่อผูกกับฟิลด์ประเภทนั้นและเริ่มการทำงานของผู้ฟังด้วยตนเองทันทีหลังจากการอัปเดต </uglyHack>
bguiz

ฉันกำลังคิดที่จะเปลี่ยนคลาสโดยใช้โปรแกรม แต่มันจะไม่เปลี่ยนสถานะของฟิลด์แบบฟอร์มในลักษณะที่ถูกต้องอย่างที่ฉันคิด ...
super9

คำตอบ:


51

เนื่องจาก AngularJS 1.3.4 คุณสามารถใช้$setDirty()ในฟิลด์ (ที่มา ) ตัวอย่างเช่นสำหรับแต่ละฟิลด์ที่มีข้อผิดพลาดและทำเครื่องหมายว่าจำเป็นคุณสามารถดำเนินการดังต่อไปนี้:

angular.forEach($scope.form.$error.required, function(field) {
    field.$setDirty();
});

87

ในกรณีของคุณ$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue);ใช้เคล็ดลับ - ทำให้ทั้งฟอร์มและฟิลด์สกปรกและต่อท้ายคลาส CSS ที่เหมาะสม

พูดตามตรงฉันพบวิธีแก้ปัญหานี้ในโพสต์ใหม่ในหัวข้อจากลิงก์จากคำถามของคุณ มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉันดังนั้นฉันจึงวางสิ่งนี้ไว้ที่นี่เป็นคำตอบแบบสแตนด์อโลนเพื่อให้ค้นหาได้ง่ายขึ้น

แก้ไข:

โซลูชันด้านบนทำงานได้ดีที่สุดสำหรับรุ่น Angular สูงถึง 1.3.3 เริ่มต้นด้วย 1.3.4 คุณควรใช้วิธีสัมผัส API ใหม่จาก$setDirty()ngModel.NgModelController


สิ่งนี้ดูเหมือนจะเปลี่ยนไปสำหรับฉันระหว่าง Angular 1.3.0-beta5 และ 1.3.0 โดยที่ 1.3.0 ช่วยให้ฟิลด์ $ บริสุทธิ์ตราบเท่าที่ $ viewValue ไม่เปลี่ยนแปลง $scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...)ที่ผมต้องทำ ดูเหมือนคำตอบด้านล่างที่ระบุว่าfield.$setDirty()เพิ่มใน Angular 1.3.4 จะเป็นทางออกที่ดีกว่า
Johann

4
ขอบคุณสำหรับบันทึกของคุณที่คุณบันทึกวันของฉัน "สูงสุด 1.3.3 เริ่มต้นด้วย 1.3.4 คุณควรใช้วิธี API ที่เพิ่งเปิดเผย"
Ahmed Mahmoud

rmag ของผู้ใช้แล้ว angular 2 ล่ะ?
user5260143

17

คุณจะต้องตั้งค่าด้วยตนเอง$dirtyไปtrueและ$pristineไปfalseสำหรับฟิลด์ หากคุณต้องการให้คลาสปรากฏในข้อมูลที่คุณป้อนคุณจะต้องเพิ่มng-dirtyและลบng-pristineคลาสออกจากองค์ประกอบด้วยตนเอง คุณสามารถใช้$setDirty()ในระดับฟอร์มเพื่อทำสิ่งนี้ทั้งหมดบนฟอร์มเอง แต่ไม่ใช่อินพุตแบบฟอร์มอินพุตแบบฟอร์มยังไม่มี$setDirty()ตามที่คุณกล่าวไว้

คำตอบนี้อาจเปลี่ยนแปลงได้ในอนาคตเนื่องจากควรเพิ่มลง$setDirty()ในอินพุตดูเหมือนจะมีเหตุผล


3
$ setPristine () อยู่ในระดับอินพุตฟิลด์ แต่ยังไม่มี $ setDirty ใน 1.2.26 :-(
Sebastian

10

หากคุณสามารถเข้าถึงNgModelController (คุณสามารถเข้าถึงได้จากคำสั่งเท่านั้น) คุณสามารถโทร

ngModel.$setViewValue("your new view value");
// or to keep the view value the same and just change it to dirty
ngModel.$setViewValue(ngModel.$viewValue);

ขอบคุณ! สิ่งที่ฉันกำลังมองหา
dreyln

10

สร้าง jsFiddle สำหรับคุณที่แก้ปัญหานี้โดยเฉพาะ เพียงแค่ตั้งค่า $ dirty เป็น true แต่ด้วยค่า$timeout 0นี้จะทำงานหลังจากโหลด DOM

ค้นหาได้ที่นี่: JsFiddle

$timeout(function () {
  $scope.form.uName.$dirty = true;
}, 0);



5

ฟังก์ชั่นผู้ช่วยในการทำงาน:

function setDirtyForm(form) {
    angular.forEach(form.$error, function(type) {
        angular.forEach(type, function(field) {
            field.$setDirty();
        });
    });
    return form;
}

สวัสดีฉันโชคไม่ดีที่ลงคะแนนนี้โดยไม่ได้ตั้งใจ ฉันจะเปลี่ยนกลับได้อย่างไร บอกเลยว่าทำไม่ได้ถ้าไม่แก้ไขคำตอบ ..
smk

ทำงานได้ดี การเพิ่มคะแนนเป็นการตรวจสอบ "form. $ error" เพื่อให้แน่ใจว่าเราไม่ใช่ช่อง "สกปรก" ที่ผู้ใช้ไม่ได้สัมผัส แต่เป็นช่องที่ถูกต้อง
Sam T

ขอบคุณ! วิธีแก้ปัญหาที่ง่ายแสนง่าย อาจจะไม่เร็วที่สุด แต่ก็ไม่ได้ทำอะไรหนัก ๆ ดังนั้นมันจึงไม่สำคัญกับ imo การทำงานที่ดี!
jwanglof

4

เชิงมุม 2

สำหรับใครก็ตามที่ต้องการทำแบบเดียวกันใน Angular 2 จะคล้ายกันมากนอกเหนือจากการยึดแบบฟอร์ม

<form role="form" [ngFormModel]="myFormModel" (ngSubmit)="onSubmit()" #myForm="ngForm">
<div class="form-group">
    <label for="name">Name</label>
    <input autofocus type="text" ngControl="usename" #name="ngForm" class="form-control" id="name" placeholder="Name">
    <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
        Name is required
    </div>
</div>
</form>
<button type="submit" class="btn btn-primary" (click)="myForm.ngSubmit.emit()">Add</button>

import { Component, } from '@angular/core';
import { FormBuilder, Validators } from '@angular/common';

@Component({
    selector: 'my-example-form',
    templateUrl: 'app/my-example-form.component.html',
    directives: []
})
export class MyFormComponent {
    myFormModel: any;

    constructor(private _formBuilder: FormBuilder) {
        this.myFormModel = this._formBuilder.group({
            'username': ['', Validators.required],
            'password': ['', Validators.required]
        });
    }

    onSubmit() {
        this.myFormModel.markAsDirty();
        for (let control in this.myFormModel.controls) {
            this.myFormModel.controls[control].markAsDirty();
        };

        if (this.myFormModel.dirty && this.myFormModel.valid) {
            // My submit logic
        }
    }
}

3

หมายเหตุเพิ่มเติมเล็กน้อยสำหรับคำตอบของ @ rmag หากคุณมีช่องว่าง แต่จำเป็นที่คุณต้องการทำให้สกปรกให้ใช้สิ่งนี้:

$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue !== undefined 
    ? $scope.myForm.username.$viewValue : '');

นี่คือคำตอบที่ช่วยฉันได้ในที่สุด!
Kirk Liemohn

-1

ฉันไม่แน่ใจว่าทำไมคุณถึงพยายามทำเครื่องหมายว่าช่องสกปรก แต่ฉันพบว่าตัวเองอยู่ในสถานการณ์ที่คล้ายกันเพราะฉันต้องการให้ข้อผิดพลาดในการตรวจสอบความถูกต้องปรากฏขึ้นเมื่อมีคนพยายามส่งแบบฟอร์มที่ไม่ถูกต้อง ฉันลงเอยด้วยการใช้ jQuery เพื่อลบ.ng-pristineแท็กคลาสและเพิ่ม.ng-dirtyแท็กคลาสลงในฟิลด์ที่เหมาะสม ตัวอย่างเช่น:

$scope.submit = function() {
    // `formName` is the value of the `name` attribute on your `form` tag
    if (this.formName.$invalid)
    {
        $('.ng-invalid:not("form")').each(function() {
            $(this).removeClass('ng-pristine').addClass('ng-dirty');
        });
        // the form element itself is index zero, so the first input is typically at index 1
        $('.ng-invalid')[1].focus();
    }
}

5
เนื่องจากเราใช้ AngularJS อยู่แล้วโซลูชัน jQuery ดูเหมือนจะใช้งานมากเกินไป หลายคนไม่ชอบใช้ jQuery กับ AngularJS เป็นต้น
StevenClontz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.