【问题标题】:How to use $broadcast with components?如何将 $broadcast 与组件一起使用?
【发布时间】:2023-03-17 23:48:01
【问题描述】:

我有一个使用组件的 Angular 1.x 应用程序,我希望能够在我的所有组件中广播消息。上下文如下:我有一个获取 websocket 消息的服务,我想将它们广播到我的所有组件控制器。

我想到了 $broadcast,但从我发现的here 来看,它需要 $scope 和 $rootScope。这与组件的使用不兼容,因为我的应用程序中没有 $scope 了。

在使用角度组件时有没有一种干净的方法来做到这一点?

【问题讨论】:

  • 您对 Angular 工作原理的理解以及对这个问题的理解略有缺陷。使用组件和/或 Controller As 时,您仍在使用 $scope,即使您没有明确引用它。。在不破坏组件模式的情况下,引用$scope 以访问$broadcast 是完全可以接受的。

标签: javascript angularjs angular1.6


【解决方案1】:

我建议不要在这种情况下使用 $braudcast。

相反,创建简单的服务,允许您的组件使用 Observables 订阅消息。您可以使用 Rxjs 创建这些 Observable,也可以使用 GoF 主题/观察者模式创建自己的 Observable。

此服务将更新 WebSocket 获取特定消息的 observables。

更好的是,看看 Rxjs WebSocket 的实现。

【讨论】:

    【解决方案2】:

    创建广播服务可能是最简洁的方法。除非组件位于单独的 Angular 应用程序模块中。这是一个基本的简单实现:

    var app = angular.module('myApp', []);
    
    app.controller('MainCtrl', function($scope, BroadcastService) {
      this.broadcast = BroadcastService;
    });
    app.component("listenerComponent", {
      template: "<h2>Listener Component</h2><section>{{ $ctrl.message }}</section>",
      controller: function($scope, BroadcastService) {
        $scope.broadcast = BroadcastService;
        this.message = $scope.broadcast.message;
        $scope.$watch('broadcast.message', function(newVal) {
          this.message = newVal;
        }.bind(this))
      }
    });
    
    app.component("broadcastComponent", {
      template: '<h2>Broadcast Component</h2><form ng-submit="$ctrl.broadcast()"><input type="text" ng-model="$ctrl.newMessage"><button>Broadcast</button></section>',
      controller: function($scope, AppService) {
        this.newMessage = '';
        this.broadcast = function() {
          AppService.post(this.newMessage);
          this.newMessage = '';
        }
      }
    });
    
    app.factory("BroadcastService", function() {
    
      return {
        message: 'Default Message',
        post: function(message) {
          this.message = message;
        }
      }
    
    })
    
    app.factory("AppService", function(BroadcastService) {
      return {
        post: function(message) {
          BroadcastService.post("AppService Post Successful!!!" + message);
        }
      }
    
    })
    <!DOCTYPE html>
    <html ng-app="myApp">
    
      <head>
        <meta charset="utf-8" />
        <title>Broadcast App</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
        <script src="app.js"></script>
      </head>
    
      <body ng-controller="MainCtrl as vm">
        <h1>Broadcast Message:</h1> {{vm.broadcast.message }}
    
        
        <listener-component></listener-component>
        <broadcast-component></broadcast-component>
      </body>
    
    </html>

    【讨论】:

      【解决方案3】:

      正如 Claies 的评论中所述,完全可以在保留组件模式的同时仅使用 $scope。 你可以像往常一样用它和 $broadcast, $emit, $on 注入组件的控制器。

      // parentController
      controller: function ($scope) {
          $scope.$broadcast('someevent', someargs);
      }
      
      // childController
      controller: function ($scope) {
          $scope.$on('someevent', function (event, args) {
              // function implementation...
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-27
        • 2017-01-26
        • 2021-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-16
        • 2019-07-31
        相关资源
        最近更新 更多