2016-12-15 13 views
12

Vì vậy, tôi đang cố gắng thực hiện một chỉ thị có thể thao tác một FormControl. Có vẻ như nếu tôi sử dụng cú pháp dài để khai báo các điều khiển biểu mẫu trong khuôn mẫu thay vào đó, tôi có thể chuyển điều khiển đến một chỉ thị để thực hiện các công cụ với nó như một liên kết @Input() trực tiếp; ví dụ: Với các mẫu sau:Angular2 v.2.3 - Có một chỉ thị truy cập FormControl được tạo ra thông qua cú pháp formControlName

<form [formGroup]="myForm"> 
    <input type="text" id="myText" [formControl]="myForm.controls['myText']" my-directive> 
</form> 

Và logic thành phần sau đây:

@Component({ 
    // Properties go here. 
}) 
class MyComponent { 
    myForm: FormGroup; 

    constructor(fb: FormBuilder) { 
     // Constructor logic... 
    } 

    ngOnInit() { 
     this.myForm = this.fb.group({ 
      "myText": [""] 
     }); 
    } 
} 

Chỉ thị sẽ trông như thế:

@Directive({ 
    selector: "[my-directive]" 
}) 
class MyDirective { 
    Input() formControl: FormControl; 
} 

Nhưng nếu tôi đang sử dụng cú pháp formControlName trong mẫu thay thế:

<form [formGroup]="myForm"> 
    <input type="text" id="myText" formControlName="myText" my-directive> 
</form> 

Làm cách nào để tôi tham khảo FormControl (ngầm định?) Được thực hiện trong chỉ thị?

+0

Đó là chưa rõ ràng những gì bạn đang yêu cầu. Bạn có thể áp dụng một chỉ thị cho một đầu vào phản ứng với một trong hai phương thức liên kết mẫu, 'formControlName =" someName "' hoặc '[formControl] =" myForm.controls ['someName'] "' gần như tôi có thể nói nó không làm cho một sự khác biệt. Nếu bạn đăng chỉ thị của bạn và tại sao nó không làm việc cho bạn thì có lẽ bạn có thể nhận được câu trả lời. – silentsod

+0

Theo như tôi biết, cú pháp formControlName không đặt cá thể FormControl trên phần tử, vì vậy mà không có ràng buộc rõ ràng, tôi không biết cách truy cập nó. Tôi đã chỉnh sửa câu hỏi, hy vọng nó rõ ràng hơn. –

Trả lời

25

Nếu bạn sử dụng NgControl, tiêm ElementRef, HostListener và xây dựng chúng ta có thể có một chỉ thị được áp dụng để tạo thành điều khiển từ hình thức phản ứng trong hai formControlName hoặc [formControl] chiêu bài và thậm chí mẫu thúc đẩy các hình thức:

import { Directive, ElementRef, HostListener } from "@angular/core"; 
import { NgControl } from "@angular/forms"; 

@Directive({ 
    selector: '[my-directive]' 
}) 
export class MyDirective { 
    constructor(private el: ElementRef, private control : NgControl) { } 

    @HostListener('input',['$event']) onEvent($event){ 
    let valueToTransform = this.el.nativeElement.value; 
    // do something with the valueToTransform 
    this.control.control.setValue(valueToTransform); 
    } 
} 

Dưới đây là một applicable demo

+0

Cảm ơn, không biết về NgControl. Chỉ cần cho sự hiểu biết mặc dù ... 1) this.control sẽ đánh giá một FormControlDirective, một chỉ thị FormControlName, hoặc một chỉ thị NgModel dựa trên tuy nhiên chúng tôi đang làm cho các hình thức? 2) this.control.control là thể hiện FormControl được sử dụng bởi this.control, và các chỉ thị được liệt kê trong 1) tất cả đều có điều này? 3) Những thay đổi trong this.control.control sẽ áp dụng cho this.control? (ví dụ this.control.control.markAsPristine() sẽ thiết lập this.control.pristine thành true?) –

+0

1) Đúng, 2) Cũng đúng nhưng tùy thuộc vào khi bạn khởi tạo điều khiển, nó có thể không được định nghĩa trong hàm tạo chỉ thị (đó là kỳ lạ, nhưng liên quan đến các sự kiện vòng đời) 3) Có. – silentsod

+0

Điều này không có tác dụng khi chỉ thị cũng đóng vai trò là người xác thực. Nó gây ra sự phụ thuộc theo chu kỳ. –

2

câu trả lời @silentsod sẽ hoạt động hoàn hảo.

1. nếu bạn cần xử lý nhiều sự kiện như bấm phím lên/xuống hoặc bất kỳ sự kiện nào khác, thì bạn có thể thực hiện theo cách tiếp cận dưới đây.
2. Ngoài ra, tốt hơn là xác định các sự kiện trong chỉ thị.

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

@Directive({ 
    selector: '[my-directive]', 
    host: { 
    '(input)':'onEvent($event)', 
    '(keydown.backspace)': 'onEvent($event, true)' 
}) 
export class MyDirective { 
    constructor(private el: ElementRef, private control : NgControl) { } 

    public onEvent($event, someEvent){ 
    let valueToTransform = this.el.nativeElement.value; 
    // do something with the valueToTransform 
    if(someEvent) { 
    //do something 
    } 
    this.control.control.setValue(valueToTransform); 
    } 
} 

Trong Html

<form [formGroup]="myForm"> 
<input type="text" id="myText" formControlName="myText" my-directive> 
</form> 
Các vấn đề liên quan