公认的组件间通信的AngularJS方法是使用组件属性进行通信。
<div ng-controller="rootCtrl as vm">
<tab-set-component tsc-click="vm.fn($event, data)">
</tab-set-component>
<table-component="vm.tableData">
</table-component>
</div>
有关定义组件属性的更多信息,请参阅AngularJS Comprehensive Directive API -- isolate scope
最佳做法
仅将.$broadcast()、.$emit() 和.$on() 用于原子事件
在整个应用程序中全局相关的事件(例如用户身份验证或应用程序关闭)。如果您想要特定于模块、服务或小部件的事件,您应该考虑服务、指令控制器或 3rd 方库
-
$scope.$watch() 应该取代对事件的需求
- 直接注入服务和调用方法对于直接通信也很有用
- 指令可以通过指令控制器直接相互通信
-- AngularJS Wiki Best Practices
控制器示例
在您的 html 中,您使用来自根控制器的 vm.fn 对吗?所以你的建议是应该调用定义根控制器的click方法,click方法会触发rootScope上定义的http请求函数,然后获取表格组件数据,然后绑定表格组件属性上的数据。
例如:
angular.module("myApp", []);
angular.module("myApp").controller("rootCtrl", function($http) {
var vm = this;
vm.tableData = { /* initial data */ };
//click handler
vm.fn = function(event, url) {
$http.get(url).then (function onFulfilled(response) {
vm.tableData = response.data;
}).catch (function onRejected(response) {
console.log(response.status);
});
};
});
上面的例子避免了混乱的$rootScope。所有的业务逻辑和数据都包含在控制器中。
控制器为table-component设置初始数据,从tab-set-component接收点击事件,发出HTTP请求,处理错误,并将数据更新到table-component。
更新 -- 使用表达式绑定
另一种方法是使用表达式绑定来传递事件:
<header-component view="root.view" on-view-change="root.view = $event.view">
</header-component>
<main-component view="root.view"></main-component>
欲了解更多信息,请参阅SO: How to pass data between sibling components in angular, not using $scope
在 1.5.3 版本中,AngularJS 将 $onChanges 生命周期挂钩添加到 $compile 服务。
app.component("mainComponent", {
template: "<p>{{$ctrl.count}}",
bindings: {view: '<'},
controller: function() {
this.count = 0;
this.$onChanges = function(changesObj) {
if (changesObj.view) {
this.count++;
console.log(changesObj.view.currentValue);
console.log(changesObj.view.previousValue);
console.log(changes)bj.view.isFirstChanged());
};
};
}
});
欲了解更多信息,请参阅AngularJS Comprehensive Directive API Reference -- Life-cycle hooks
另见SO: AngularJs 1.5 - Component does not support Watchers, what is the work around?