在Angular 1.x中传达组件或指令的有效方法

Sev*_*Lee 3 components watch angularjs angularjs-directive

根据下图:

在此输入图像描述

我想改进组件通信方法....我认为这种方式效率不高.

单击tabsetComponent以发出事件时,父控制器会捕获此事件,从而更改rootScope变量.在tableComponent中使用$ watch rootScope变量来触发http获取数据函数...

谁能有更好,更有效的方式来沟通兄弟组件?

geo*_*awg 5

用于组件之间通信的公认的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>
Run Code Online (Sandbox Code Playgroud)

有关定义组件属性的更多信息,请参阅AngularJS综合指令API - 隔离范围

最佳做法

仅使用.$broadcast(),.$emit().$on()为原子事件

在整个应用程序中全局相关的事件(例如用户身份验证或应用程序关闭).如果您需要特定于模块,服务或小部件的事件,则应考虑服务,指令控制器或第三方库

  • $scope.$watch() 应该取代事件的需要
  • 直接注入服务和调用方法对于直接通信也很有用
  • 指令能够通过指令控制器直接相互通信

- AngularJS Wiki最佳实践


控制器示例

在您的HTML中,您使用vm.fn来自根控制器的权利吗?所以你的建议是应该调用click方法定义root控制器,click方法会触发定义的http请求函数rootScope,然后获取表组件数据,然后绑定表组件属性上的数据.

例如:

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);
        });
    };
});
Run Code Online (Sandbox Code Playgroud)

上面的例子避免了混乱$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>
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅SO:如何以角度方式在兄弟组件之间传递数据,而不是使用$ 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());
            };
        };    
      }
});
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅AngularJS综合指令API参考 - 生命周期挂钩

另请参见SO:AngularJs 1.5 - 组件不支持Watchers,解决方法是什么?