在 Angular 1.x 中通信组件或指令的有效方式
Posted
技术标签:
【中文标题】在 Angular 1.x 中通信组件或指令的有效方式【英文标题】:Efficient way to communicate components or directives in Angular 1.x 【发布时间】:2016-06-02 06:23:50 【问题描述】:根据下图:
我想改进组件通信方式....我认为这种方式效率不高。
当点击 tabsetComponent 发出事件时,父控制器会捕捉到这个事件,改变 rootScope 变量。使用tableComponent中的$watch rootScope变量触发http获取数据函数...
谁能有更好更有效的方式来交流兄弟组件?
【问题讨论】:
【参考方案1】:公认的组件间通信的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?
【讨论】:
在您的 html 中,您使用来自根控制器的 vm.fn 对吗?所以你的建议是它应该调用根控制器上定义的click方法,click方法将触发rootScope上定义的http请求函数,然后获取表组件数据,然后绑定表组件属性上的数据。你认为在根控制器中定义 http fetch 函数效率更高吗?而且通过这些方式,我们不需要使用任何事件方法,对吗? 查看添加的控制器示例 感谢您的详细解释:) 另一个问题,如果根范围内有很多组件,我们将在根控制器中定义很多功能,是正确的方法吗?根控制器会太重而无法高效执行? 上面的控制器示例没有使用$rootScope
。它使用$rootScope
的子作用域。您可以通过将'scope-id'=+$id
放入其模板中来检查。 $rootScope
的 ID 为 1。子作用域的数字从 1 递增。
对不起,我打错字了...其实我想说的是,如果我在根控制器中定义了很多根控制器中的组件需要的功能,那么根控制器会不会太重?以上是关于在 Angular 1.x 中通信组件或指令的有效方式的主要内容,如果未能解决你的问题,请参考以下文章
Angular (v2) 扩展系列组件通信(无父或外部服务)
在 Angular 结构指令中使用动态组件会产生额外的 HTML 标记。如何删除或更换它?