【问题标题】:How to communicate between component in Angular?如何在Angular中的组件之间进行通信?
【发布时间】:2018-11-06 22:18:25
【问题描述】:

我正在开发一个 Web 应用程序项目,并且我正在尝试使用 Angular,但组件通信出现了一些问题。例如,父组件如何与子组件交换数据,兄弟组件之间如何通信。

【问题讨论】:

  • 取决于你想做什么。您是尝试进行 rpc、消息传递还是仅共享变量?

标签: angular components


【解决方案1】:

如果您尝试从父组件与子组件进行通信,则在角度文档中使用 @Input 和 EventEmitters 以及 @Output 非常清楚地描述了这一点。

Angular 2 component interaction

至于兄弟之间的通信,我在一个类似的问题中发布了一个答案,这可能有助于解决兄弟组件之间共享数据的问题。目前,我认为共享服务方式是最有效的。

angular-2-sibling-component-communication

【讨论】:

  • 我发现答案很有用并对其表示赞同,但随后在另一页中看到它主要与 Angular 2 相关:Alex J 的答案很好,但截至 7 月它不再适用于当前的 Angular 4 , 2017
【解决方案2】:

使用服务:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class AppState {
  public _subject = new Subject<object>();
  public event = this._subject.asObservable();

  public publish(data: any) {
    this._subject.next(data);
  }
}

您可以像这样发布类似事件的消息:

export class AppComponent {
  constructor(
    public appState: AppState
  ) {
    appState.publish({data: 'some data'});
  }
}

您可以订阅这些事件:

export class HomeComponent {
  constructor(
    public appState: AppState
  ) {
    appState.event.subscribe((data) => {
      console.log(data); // {data: 'some data'}
    });
  }
}

【讨论】:

【解决方案3】:
  1. @Input 和@Output

    如果有多部分组件 您可以使用@Input 和@Output 来交换数据。 文档:https://angular.io/guide/component-interaction

    示例:https://angular.io/generated/live-examples/component-interaction/eplnkr.html

  2. 依赖注入

    您可以将数据存储在Service中,然后将Service注入您想要的组件中。如示例中的“user.server.ts”:

    https://angular.io/generated/live-examples/dependency-injection/eplnkr.html

【讨论】:

  • 第二个链接坏了,如果可能请修复它
【解决方案4】:

您将需要使用依赖注入。这是一个小例子: https://github.com/gdi2290/angular2do/blob/gh-pages/app/components/todo-item/todo-item.js

【讨论】:

    【解决方案5】:

    using DataService stackbliz

    sender.ts

    import { Component } from '@angular/core';
    import {dataService} from './dataservice.service';
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      //name = 'Angular';
      constructor(private SVC: dataService ){
    
      }
      sender(){
        this.SVC.name="sender"
        console.log("sending this string:    "+this.SVC.name)
      }
    
    }
    

    dataservice.ts

       import { Injectable } from '@angular/core';
    
        @Injectable()
        export class dataService {
        name=""
          constructor() { }
        }
    

    receiver.ts

    import { Component, OnInit } from '@angular/core';
    import {dataService} from '../dataservice.service';
    @Component({
      selector: 'app-recieved',
      templateUrl: './recieved.component.html',
      styleUrls: ['./recieved.component.css']
    })
    export class RecievedComponent implements OnInit {
      constructor(private dataservice: dataService ){
    
      }
      ngOnInit() { 
      }
    print(){
      console.log("recieved:    " +this.dataservice.name)
    }
    }
    

    【讨论】:

      【解决方案6】:

      Angular 中有 Events API 可以为您完成。

      Click here for more details on Events.

      下面是我目前在项目中使用的一个简单示例。希望对有需要的人有所帮助。

      从“离子角度”导入{事件};

      用法:

        constructor(public events: Events) {
              /*=========================================================
              =  Keep this block in any component you want to receive event response to            =
              ==========================================================*/
              // Event Handlers
              events.subscribe('menu:opened', () => {
                  // your action here
                  console.log('menu:opened');
              });
              events.subscribe('menu:closed', () => {
                  // your action here
                  console.log('menu:closed');
              });
          }
      
          /*=====================================================
          = Call these on respective events - I used them for Menu open/Close          =
          ======================================================*/
      
          menuClosed() {
              // Event Invoke
              this.events.publish('menu:closed', '');
          }
          menuOpened() {
              // Event Invoke
              this.events.publish('menu:opened', '');
          }
      
        }
      

      【讨论】:

        【解决方案7】:

        通过使用以下任何一种方法,我们可以连接 2 个组件。

        1. 使用@input()
        2. 使用@output()
        3. 使用服务。
        4. 父组件调用viewchild。
        5. 父母使用局部变量与孩子互动。

        【讨论】:

          【解决方案8】:

          在AngularJS中可以实现组件间的通信。在 AngularJS 中,我们有一个称为 require 属性的东西,它需要映射到组件中。按照下面的示例,它将从组件 myPane 访问组件 myTabs 的函数 addPane(parameter): -

          项目结构:

          HTML

          1. index.html
          2. my-tabs.html
          3. my-pane.html

          JS

          1. script.js

          script.js

          angular.module('docsTabsExample', [])
              .component('myTabs', {
                transclude: true,
                controller: function MyTabsController() {
                  var panes = this.panes = [];
                  this.select = function(pane) {
                    angular.forEach(panes, function(pane) {
                      pane.selected = false;
                    });
                    pane.selected = true;
                  };
                  this.addPane = function(pane) {
                    if (panes.length === 0) {
                      this.select(pane);
                    }
                    panes.push(pane);
                  };
                },
                templateUrl: 'my-tabs.html'
              })
              .component('myPane', {
                transclude: true,
                require: {          //This property will be used to map other component
                  tabsCtrl: '^myTabs' // Add ^ symbol before the component name which you want to map.
                },
                bindings: {
                  title: '@'
                },
                controller: function() {
                  this.$onInit = function() {
                    this.tabsCtrl.addPane(this);  //Calling the function addPane from other component.
                    console.log(this);
                  };
                },
                templateUrl: 'my-pane.html'
              });

          index.html

          <my-tabs>
            <my-pane title="Hello">
              <h4>Hello</h4>
              <p>Lorem ipsum dolor sit amet</p>
            </my-pane>
            <my-pane title="World">
              <h4>World</h4>
              <em>Mauris elementum elementum enim at suscipit.</em>
              <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
            </my-pane>
          </my-tabs>

          my-tabs.html

          <div class="tabbable">
            <ul class="nav nav-tabs">
              <li ng-repeat="pane in $ctrl.panes" ng-class="{active:pane.selected}">
                <a href="" ng-click="$ctrl.select(pane)">{{pane.title}}</a>
              </li>
            </ul>
            <div class="tab-content" ng-transclude></div>
          </div>

          my-pane.html

          &lt;div class="tab-pane" ng-show="$ctrl.selected" ng-transclude&gt;&lt;/div&gt;

          代码 sn-p : https://plnkr.co/edit/diQjxq7D0xXTqPunBWVE?p=preview

          参考:https://docs.angularjs.org/guide/component#intercomponent-communication

          希望这会有所帮助:)

          【讨论】:

            猜你喜欢
            • 2015-12-17
            • 1970-01-01
            • 2017-01-01
            • 2017-07-18
            • 2018-08-07
            • 2017-03-06
            • 2023-04-06
            • 1970-01-01
            相关资源
            最近更新 更多