27

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

4

8 回答 8

18

使用服务:

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'}
    });
  }
}
于 2017-03-30T09:37:47.023 回答
18

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

Angular 2 组件交互

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

angular-2-sibling-component-communication

于 2016-03-15T18:16:35.400 回答
12
  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

于 2016-02-18T15:24:13.510 回答
4

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

于 2015-05-28T09:01:43.903 回答
1

使用数据服务 stackbliz

发件人.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)
  }

}

数据服务.ts

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

    @Injectable()
    export class dataService {
    name=""
      constructor() { }
    }

接收器.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)
}
}
于 2019-11-19T10:16:52.380 回答
0

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

  1. 使用@input()
  2. 使用@output()
  3. 使用服务。
  4. 父组件调用 viewchild。
  5. 父母使用局部变量与孩子互动。
于 2021-02-19T09:37:17.710 回答
0

Angular中有Events API可以为你做。

单击此处了解有关活动的更多详细信息。

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

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

用法 :

  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', '');
    }

  }
于 2017-09-15T04:55:16.680 回答
-1

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

项目结构:

HTML

  1. 索引.html
  2. 我的-tabs.html
  3. 我的-pane.html

JS

  1. 脚本.js

脚本.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'
    });

索引.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>

我的-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>

我的-pane.html

<div class="tab-pane" ng-show="$ctrl.selected" ng-transclude></div>

代码片段:https ://plnkr.co/edit/diQjxq7D0xXTqPunBWVE?p=preview

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

希望这可以帮助 :)

于 2018-03-16T09:02:00.147 回答