angular - Angular 中的全局事件

标签 angular events

在 Angular 中是否没有等同于 $scope.emit()$scope.broadcast() 的东西?

我知道 EventEmitter 功能,但据我所知,它只会向父 HTML 元素发出一个事件。

如果我需要在fx之间进行通信怎么办。 sibling 或 DOM 根中的组件与嵌套多层的元素之间?

最佳答案

AngularJS 中没有等同于 $scope.emit()$scope.broadcast() 的东西。 组件内部的 EventEmitter 接近,但正如您提到的,它只会向直接父组件发出事件。

在 Angular 中,还有其他替代方案,我将在下面尝试解释。

@Input() 绑定(bind)允许应用程序模型连接到有向对象图中(根到叶)。组件的更改检测器策略的默认行为是将所有更改传播到来自任何连接组件的所有绑定(bind)的应用程序模型。

旁白:有两种类型的模型: View 模型和应用程序模型。应用程序模型通过@Input() 绑定(bind)连接。 View 模型只是一个绑定(bind)在组件模板中的组件属性(未使用 @Input() 修饰)。

回答您的问题:

如果我需要在同级组件之间进行通信怎么办?

  1. 共享应用模型: sibling 可以通过共享应用程序模型进行通信(就像 Angular 1)。例如,当一个兄弟对模型进行更改时,绑定(bind)到同一模型的另一个兄弟会自动更新。

  2. 组件事件:子组件可以使用@Output() 绑定(bind)向父组件发出事件。父组件可以处理事件,并操纵应用程序模型或它自己的 View 模型。对应用程序模型的更改会自动传播到直接或间接绑定(bind)到同一模型的所有组件。

  3. 服务事件:组件可以订阅服务事件。例如,两个兄弟组件可以订阅同一个服务事件并通过修改各自的模型来响应。更多内容见下文。

如何在 Root 组件和嵌套多层的组件之间进行通信?

  1. 共享应用程序模型:应用程序模型可以通过@Input() 绑定(bind)从根组件向下传递到深层嵌套的子组件。任何组件对模型的更改都会自动传播到共享同一模型的所有组件。
  2. 服务事件:您还可以将 EventEmitter 移动到共享服务,这允许任何组件注入(inject)服务并订阅事件。这样,Root 组件可以调用服务方法(通常是改变模型),该方法又会发出一个事件。往下几层,孙组件也注入(inject)了服务并订阅了相同的事件,可以处理它。任何更改共享应用程序模型的事件处理程序都将自动传播到依赖它的所有组件。这可能与 Angular 1 中的 $scope.broadcast() 最接近。下一节将更详细地描述这个想法。

使用服务事件传播变化的可观察服务示例

这是一个使用服务事件传播变化的可观察服务示例。添加 TodoItem 时,服务会发出一个事件,通知其组件订阅者。

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);
    }
}

这是根组件订阅事件的方式:

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;
    }
}

嵌套多层的子组件将以相同的方式订阅事件:

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;
    }
}

这里是调用服务触发事件的组件(它可以驻留在组件树中的任何位置):

@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));
    }
}

引用:Change Detection in Angular

关于angular - Angular 中的全局事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34700438/

相关文章:

Angular 2 事件发射器与主题

angular - *ngFor 循环遍历数组 Angular6

javascript - d3 发送鼠标事件到div子元素

javascript - ASP.NET 计时器 + 更新面板 : How do I stop the event from continually registering?

c++ - 如何知道 wxFrame 何时关闭?

angular - Angular 的 Kendo UI : how to define min-width in grid

angular - 在 Redis 中缓存 Angular2 包?好还是不好?

javascript - 表单输入状态颜色不变

javascript - 不断检查对象值,如果为 false 则结束进程

c# - 在控件容器中捕获 Click/DoubleClick 事件?