this.eventsService.broadcast('something', "Am I a?", "Should be b", "C?");
this.eventsService.on('something', function (a, b, c) {
console.log(a, b, c);
});
export Class myService {
#all the stuff that must exist
myString: string[] = [];
contactChange : BehaviorSubject<string[]> = new BehaviorSubject(this.myString);
getContacts(newContacts) {
// get your data from a webservices & when you done simply next the value
this.contactChange.next(newContacts);
}
}
export Class myComp {
#all the stuff that exists like @Component + constructor using (private myService: myService)
this.myService.contactChange.subscribe((contacts) => {
this.contactList += contacts; //run everytime next is called
}
}
10 回答
没有相当于AngularJS的
$scope.emit()
或$scope.broadcast()
. 组件内部的EventEmitter接近,但正如您所提到的,它只会向直接父组件发出一个事件 .在Angular中,还有其他替代方案,我将在下面解释 .
@Input()绑定允许应用程序模型在有向对象图(根到叶)中连接 . 组件的更改检测器策略的默认行为是将所有更改传播到应用程序模型,以用于来自任何连接组件的所有绑定 .
旁白:有两种类型的模型:视图模型和应用程序模型 . 应用程序模型通过@Input()绑定连接 . 视图模型只是一个组件属性(未使用@Input()修饰),它绑定在组件的模板中 .
回答你的问题:
如果我需要在兄弟组件之间进行通信怎么办?
Shared Application Model :兄弟姐妹可以通过共享应用程序模型进行通信(就像角度1一样) . 例如,当一个兄弟对模型进行更改时,另一个绑定到同一模型的兄弟会自动更新 .
Component Events :子组件可以使用@Output()绑定向父组件发出事件 . 父组件可以处理事件,并操纵应用程序模型或它自己的视图模型 . 对应用程序模型的更改会自动传播到直接或间接绑定到同一模型的所有组件 .
Service Events :组件可以订阅服务事件 . 例如,两个兄弟组件可以订阅相同的服务事件,并通过修改其各自的模型进行响应 . 更多关于此的信息 .
如何在Root组件和嵌套多个级别的组件之间进行通信?
Shared Application Model :应用程序模型可以通过@Input()绑定从Root组件传递到深层嵌套的子组件 . 从任何组件对模型的更改将自动传播到共享相同模型的所有组件 .
Service Events :您还可以将EventEmitter移动到共享服务,该服务允许任何组件注入服务并订阅事件 . 这样,Root组件可以调用服务方法(通常是改变模型),然后发出一个事件 . 几个层向下,一个也注入了服务并订阅同一事件的grand-child组件可以处理它 . 任何更改共享应用程序模型的事件处理程序都将自动传播到依赖于它的所有组件 . 这可能是与Angular 1中最接近的
$scope.broadcast()
. 下一节将更详细地描述这个想法 .Example of an Observable Service that uses Service Events to Propagate Changes
以下是使用服务事件传播更改的可观察服务的示例 . 添加TodoItem时,服务会发出通知其组件订阅者的事件 .
以下是根组件订阅事件的方式:
嵌套了几个级别的子组件将以相同的方式订阅该事件:
以下是调用服务来触发事件的组件(它可以驻留在组件树中的任何位置):
参考:Change Detection in Angular
以下代码作为Angular 2中 $scope.emit() 或 $scope.broadcast() 的替换示例,使用 shared service 来处理事件 .
用法示例:
广播:
监听器:
它可以支持多个参数:
我正在使用包装rxjs的消息服务
Subject
(TypeScript)Plunker example: Message Service
组件可以订阅和广播事件(发件人):
(接收器)
MessageService
的subscribe
方法返回一个rxjsSubscription
对象,可以取消订阅,如下所示:另见这个答案:https://stackoverflow.com/a/36782616/1861779
Plunker example: Message Service
DO Not Use EventEmitter用于您的服务通信 .
您应该使用Observable类型之一 . 我个人喜欢BehaviorSubject .
Simple example:
你可以传递初始状态,这里我传递null
当您想要更新主题时
观察任何服务或组件,并在获得新的更新时采取行动 .
Here is more information. .
您可以使用EventEmitter或observables创建您在DI中注册的eventbus服务 . 每个想要参与的组件只是将服务作为构造函数参数请求并发出和/或订阅事件 .
也可以看看
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
Delegation: EventEmitter or Observable in Angular2
我在这里创建了一个pub-sub示例:
http://www.syntaxsuccess.com/viewarticle/pub-sub-in-angular-2.0
想法是使用RxJs主题将Observer和Observables连接起来作为发布和订阅自定义事件的通用解决方案 . 在我的示例中,我使用客户对象进行演示
这是一个现场演示:http://www.syntaxsuccess.com/angular-2-samples/#/demo/pub-sub
我最喜欢的方法是在我的服务中使用行为主题或事件 Launcher (几乎相同)来控制我的所有子组件 .
使用angular cli,运行ng s以创建新服务,然后使用BehaviorSubject或EventEmitter
当您这样做时,使用您的服务作为提供者的每个组件都将意识到这一变化 . 只需像使用eventEmitter一样订阅结果;)
我们实现了一个ngModelChange observable指令,该指令通过您在自己的组件中实例化的事件 Launcher 发送所有模型更改 . 您只需将事件 Launcher 绑定到指令即可 .
见:https://github.com/atomicbits/angular2-modelchangeobservable
在html中,绑定您的事件 Launcher (在此示例中为countryChanged):
在您的打字稿组件中,对EventEmitter执行一些异步操作:
这是我的版本:
使用:
}
发射:
服务事件:组件可以订阅服务事件 . 例如,两个兄弟组件可以订阅相同的服务事件,并通过修改其各自的模型进行响应 . 更多关于此的信息 .
但请确保在销毁父组件时取消订阅 .