Không có tương đương với $scope.emit()
hoặc $scope.broadcast()
từ AngularJS. EventEuctor bên trong một thành phần đến gần, nhưng như bạn đã đề cập, nó sẽ chỉ phát ra một sự kiện cho thành phần cha mẹ ngay lập tức.
Trong Angular, có những lựa chọn thay thế khác mà tôi sẽ cố gắng giải thích bên dưới.
Các ràng buộc @Input () cho phép mô hình ứng dụng được kết nối trong biểu đồ đối tượng được định hướng (từ gốc đến lá). Hành vi mặc định của chiến lược phát hiện thay đổi của một thành phần là tuyên truyền tất cả các thay đổi cho một mô hình ứng dụng cho tất cả các ràng buộc từ bất kỳ thành phần nào được kết nối.
Ngoài ra: Có hai loại mô hình: Xem mô hình và Mô hình ứng dụng. Một mô hình ứng dụng được kết nối thông qua các ràng buộc @Input (). Mô hình khung nhìn chỉ là một thuộc tính thành phần (không được trang trí bằng @Input ()) được ràng buộc trong mẫu của thành phần.
Để trả lời câu hỏi của bạn:
Nếu tôi cần liên lạc giữa các thành phần anh chị em thì sao?
Mô hình ứng dụng được chia sẻ : Anh chị em có thể giao tiếp thông qua mô hình ứng dụng được chia sẻ (giống như góc 1). Ví dụ: khi một anh chị em thực hiện thay đổi cho một mô hình, anh chị em khác có các ràng buộc với cùng một mô hình sẽ được cập nhật tự động.
Sự kiện thành phần : Các thành phần con có thể phát ra một sự kiện đến thành phần cha mẹ bằng cách sử dụng các ràng buộc @Output (). Thành phần cha mẹ có thể xử lý sự kiện và thao tác mô hình ứng dụng hoặc mô hình khung nhìn của chính nó. Các thay đổi đối với Mô hình ứng dụng được tự động truyền tới tất cả các thành phần liên kết trực tiếp hoặc gián tiếp với cùng một mô hình.
Sự kiện dịch vụ : Các thành phần có thể đăng ký các sự kiện dịch vụ. Ví dụ: hai thành phần anh chị em có thể đăng ký vào cùng một sự kiện dịch vụ và phản hồi bằng cách sửa đổi các mô hình tương ứng của chúng. Thêm về điều này dưới đây.
Làm thế nào tôi có thể giao tiếp giữa một thành phần Root và một thành phần lồng nhau sâu vài cấp?
- Mô hình ứng dụng được chia sẻ : Mô hình ứng dụng có thể được chuyển từ thành phần Root xuống các thành phần phụ được lồng sâu thông qua các ràng buộc @Input (). Thay đổi đối với một mô hình từ bất kỳ thành phần nào sẽ tự động truyền tới tất cả các thành phần có chung mô hình.
- Sự kiện dịch vụ : Bạn cũng có thể di chuyển EventEuctor sang dịch vụ chia sẻ, cho phép mọi thành phần tiêm dịch vụ và đăng ký sự kiện. Theo cách đó, một thành phần Root có thể gọi một phương thức dịch vụ (thường làm biến đổi mô hình), từ đó phát ra một sự kiện. Một số lớp xuống, một thành phần lớn cũng đã tiêm dịch vụ và đăng ký vào cùng một sự kiện, có thể xử lý nó. Bất kỳ trình xử lý sự kiện nào thay đổi Mô hình ứng dụng được chia sẻ, sẽ tự động truyền tới tất cả các thành phần phụ thuộc vào nó. Đây có lẽ là tương đương gần nhất với
$scope.broadcast()
từ Angular 1. Phần tiếp theo mô tả ý tưởng này chi tiết hơn.
Ví dụ về Dịch vụ quan sát được sử dụng Sự kiện dịch vụ để tuyên truyền các thay đổi
Dưới đây là một ví dụ về một dịch vụ quan sát được sử dụng các sự kiện dịch vụ để tuyên truyền các thay đổi. Khi một TodoItem được thêm vào, dịch vụ sẽ phát ra một sự kiện thông báo cho các thuê bao thành phần của nó.
export class TodoItem {
constructor(public name: string, public done: boolean) {
}
}
export class TodoService {
public itemAdded$: EventEmitter<TodoItem>;
private todoList: TodoItem[] = [];
constructor() {
this.itemAdded$ = new EventEmitter();
}
public list(): TodoItem[] {
return this.todoList;
}
public add(item: TodoItem): void {
this.todoList.push(item);
this.itemAdded$.emit(item);
}
}
Đây là cách một thành phần gốc sẽ đăng ký sự kiện:
export class RootComponent {
private addedItem: TodoItem;
constructor(todoService: TodoService) {
todoService.itemAdded$.subscribe(item => this.onItemAdded(item));
}
private onItemAdded(item: TodoItem): void {
// do something with added item
this.addedItem = item;
}
}
Một thành phần con được lồng sâu vài cấp sẽ đăng ký vào sự kiện theo cùng một cách:
export class GrandChildComponent {
private addedItem: TodoItem;
constructor(todoService: TodoService) {
todoService.itemAdded$.subscribe(item => this.onItemAdded(item));
}
private onItemAdded(item: TodoItem): void {
// do something with added item
this.addedItem = item;
}
}
Đây là thành phần gọi dịch vụ để kích hoạt sự kiện (nó có thể nằm ở bất kỳ đâu trong cây thành phần):
@Component({
selector: 'todo-list',
template: `
<ul>
<li *ngFor="#item of model"> {{ item.name }}
</li>
</ul>
<br />
Add Item <input type="text" #txt /> <button (click)="add(txt.value); txt.value='';">Add</button>
`
})
export class TriggeringComponent{
private model: TodoItem[];
constructor(private todoService: TodoService) {
this.model = todoService.list();
}
add(value: string) {
this.todoService.add(new TodoItem(value, false));
}
}
Tham khảo: Phát hiện thay đổi trong góc