在 Angular 1.x 中交流组件或指令的有效方式
Efficient way to communicate components or directives in Angular 1.x
根据下图:
我想改进组件通信方法....我认为这种方式效率不高。
当点击 tabsetComponent 发出事件时,父控制器捕捉到这个事件,改变 rootScope 变量。使用tableComponent中的$watch rootScope变量触发http获取数据功能...
谁能有更好更有效的方法来交流同级组件?
公认的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
Best practices
Only use .$broadcast()
, .$emit()
and .$on()
for atomic events
Events that are relevant globally across the entire app (such as a user authenticating or the app closing). If you want events specific to modules, services or widgets you should consider Services, Directive Controllers, or 3rd Party Libs
$scope.$watch()
should replace the need for events
- Injecting services and calling methods directly is also useful for direct communication
- Directives are able to directly communicate with each other through directive-controllers
-- AngularJS Wiki Best Practices
控制器示例
In your html, you use vm.fn
that came from root controller right? So your advice is it should call the click method defined root controller, the click method will trigger http request function defined on the rootScope
, then get table component datas, then bind the datas on table component attribute.
例如:
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>
有关详细信息,请参阅
在版本 1.5.3 中,AngularJS 向 $compile
服务添加了 $onChanges
生命周期挂钩。
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
另见
根据下图:
我想改进组件通信方法....我认为这种方式效率不高。
当点击 tabsetComponent 发出事件时,父控制器捕捉到这个事件,改变 rootScope 变量。使用tableComponent中的$watch rootScope变量触发http获取数据功能...
谁能有更好更有效的方法来交流同级组件?
公认的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
Best practices
Only use
.$broadcast()
,.$emit()
and.$on()
for atomic eventsEvents that are relevant globally across the entire app (such as a user authenticating or the app closing). If you want events specific to modules, services or widgets you should consider Services, Directive Controllers, or 3rd Party Libs
$scope.$watch()
should replace the need for events- Injecting services and calling methods directly is also useful for direct communication
- Directives are able to directly communicate with each other through directive-controllers
-- AngularJS Wiki Best Practices
控制器示例
In your html, you use
vm.fn
that came from root controller right? So your advice is it should call the click method defined root controller, the click method will trigger http request function defined on therootScope
, then get table component datas, then bind the datas on table component attribute.
例如:
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>
有关详细信息,请参阅
在版本 1.5.3 中,AngularJS 向 $compile
服务添加了 $onChanges
生命周期挂钩。
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
另见