2016-08-08 19 views
7

Tôi đã có một 2 điều khiển góc mà trông như thế này:Góc 2: làm cách nào để phát hiện các thay đổi thuộc tính đối với các thuộc tính đầu vào trên một Thành phần?

@Component({ 
    selector: 'my-component', 
    template: '<div>The value is: {{ value }}</div>', 
}) 
class MyComponent implements OnInit { 
    @Input() 
    value: string; 

    @Output 
    valueChange = new EventEmitter<number>(); 

    ngOnInit() { 
    this.valueChange.subscribe(value => { 
     console.log('new value:', value); // <-- does not get triggered 
    }); 
    } 
} 

Nhưng khi giá trị của value thay đổi từ một mẫu ràng buộc:

<my-component [value]="someValue" /> <!-- valueChange not triggered! --> 

Sự kiện valueChange không được kích hoạt như vậy, mặc dù mẫu chính xác cập nhật và hiển thị giá trị mới, thành phần không biết nó đã bị thay đổi.

Làm cách nào để phát hiện khi thuộc tính đầu vào trên bộ điều khiển của tôi bị thay đổi?

Trả lời

2

tôi đã có thể làm việc xung quanh vấn đề này bằng cách thực hiện từ OnChanges:

ngOnChanges(changes) { 
    for (let key in changes) { 
    if (this[key + 'Change']) 
     this[key + 'Change'].emit(changes[key].currentValue); 
    } 
} 

Mà sẽ tự động kích hoạt các sự kiện Change bất cứ khi nào kiễu góc phát hiện một sự thay đổi ... nhưng có cách nào để làm điều này natively?

12

Theo ý kiến ​​của tôi, Output là để thành viên của bạn phát ra sự kiện cho người khác để họ cập nhật chế độ xem nếu cần, nó chỉ được sử dụng cho các thay đổi được thực hiện nội bộ cần được phát sóng (do đó tên là Output). Kích hoạt sự kiện Output trên Input thay đổi có thể gây ra hành vi không mong muốn (vì bây giờ valueChange được kích hoạt cho tất cả các thay đổi cả bên trong lẫn bên ngoài và không thực sự là Output nữa).

Trong trường hợp của bạn, nếu bạn muốn làm công cụ khi value thay đổi của bạn, bạn có thể biến nó thành một setter:

private _value: string; 
get value(): string { 
    return this._value; 
} 

@Input('value') 
set value(val: string) { 
    this._value = val; 
    console.log('new value:', value); // <-- do your logic here! 
} 
7

Tôi đã sử dụng setters để phát hiện khi các biến đầu vào đã được sửa đổi. Bạn phải sử dụng các inputs quan trọng trong việc trang trí @Component thay vì @Input khai để có được điều này để làm việc, như vậy:

@Component({ 
    selector: 'my-component', 
    template: '<div>The value is: {{ value }}</div>', 
    inputs: ['value'] 
}) 
class MyComponent { 
    private _value: string; 

    @Output 
    valueChange = new EventEmitter<number>(); 

    set value(value) { 
    this._value = value; 
    console.log('new value:', value); 
    this.valueChange.emit(value); 
    } 

    get value(value) { 
    return this._value; 
    } 
} 

Cũng FYI, phương pháp lớp là ngOnInit thay vì onInit.

+1

Bạn có thể sử dụng thuộc tính đầu vào trên \ @Component decorator * hoặc * bạn có thể sử dụng \ @Input decorator trên thuộc tính đã đặt. Cả hai đều hoạt động và trình trang trí \ @Input dường như là cách ưa thích hiện tại –

+0

Trình truy cập nhận được và không thể có giá trị, bạn có thể muốn cập nhật phương thức get của bạn thành 'get value() {}' . '@ output' của bạn cũng có thể cần được cập nhật thành' @Output() ' –

Các vấn đề liên quan