简体   繁体   English

如何将数据从子级传递到父级:Angular2

[英]How to pass data from Child to Parent: Angular2

I'm following the docs here: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#child-to-parent 我在这里关注文档: https : //angular.io/docs/ts/latest/cookbook/component-communication.html#!# child-to-parent

However so far not able to get a string variable from the child into the parent. 但是到目前为止,还不能将字符串变量从子级获取到父级。


The Child 孩子

Here I'm sending the category title to the emitter 在这里,我将类别标题发送给发射器

import { Component,
         ChangeDetectionStrategy,
         EventEmitter,
         Output,
         OnInit,
         ViewEncapsulation } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
    changeDetection: ChangeDetectionStrategy.Default,
    encapsulation: ViewEncapsulation.Emulated,
    selector: 'category',
    styleUrls: [ './category.component.css' ],
    templateUrl: './category.component.html'
})
export class CategoryComponent implements OnInit {
    title: string = '';
    @Output() onCategoryTitled = new EventEmitter<string>();

    constructor(private route: ActivatedRoute) {}

    ngOnInit() {
        this.title = this.route.snapshot.params['title'];
        console.log('this.title', this.title)
        this.onCategoryTitled.emit(this.title);
    }
}

The Parent app.component 父app.component

Here is the parent, I'm able to see the log from the child, but not the log here 这是父母,我可以看到孩子的日志,但这里看不到日志

import { Component,
         Directive,
         ElementRef,
         Renderer,
         ChangeDetectionStrategy,
         OnInit,
         ViewEncapsulation } from '@angular/core';

@Component({
    changeDetection: ChangeDetectionStrategy.Default,
    encapsulation: ViewEncapsulation.Emulated,
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    catTitle:string;

    onCategoryTitled(cat_title: string) {
        console.log('EVENT recieved cat_title:', cat_title)
        this.catTitle = cat_title;
    }

    ngOnInit() {
        console.log('AppComponent init')
    }
}

Parent markup (Where I need the title) 家长标记(需要标题的地方)

<div class="container">
    <div class="row"><div class="col-md-12 h20"></div></div>

    <div class="row">
        <div class="col-md-8 col-sm-8">
            <ol class="breadcrumb">
                <li><a href="/wiki">Home</a></li>
                <li>{{ catTitle }}</li>
                <!-- <li><a href="/wiki/category">Categories</a></li> -->
            </ol>
        </div>

        <div class="col-md-2 col-sm-2">
            <div class="input-group">
                <input type="text" class="search-input form-control" placeholder="Search for...">
            </div>
        </div>
    </div>

    <router-outlet></router-outlet>

    <footer class="container col-sm-12">
        <p>©2017 <strong>WikiTags</strong>
    </footer>

</div>

在此处输入图片说明

The method of communication that you're attempting from The Cookbook is to be used when the Child is nested directly in the Parent. 当子级直接嵌套在父级中时,将使用您从The Cookbook中尝试的通信方法。 In that case, on the Parent you would bind your event handler to the emitted event like in their example: 在这种情况下,您可以在Parent上将事件处理程序绑定到发出的事件,如其示例所示:

(onVoted)="onVoted($event)"

Your case is a bit different because you have router-outlet that dynamically loads the component into the parent, and that introduces a bit more complexity. 您的情况有所不同,因为您具有router-outlet ,该router-outlet将组件动态地加载到父级中,并且引入了更多的复杂性。 You still need to bind (or subscribe) to the event, but (as you may have encountered) you can't add the binding directly to the router-outlet as that simpler cookbook example shows. 您仍然需要绑定(或订阅)该事件,但是(如您可能遇到的那样)您不能像该简单的菜谱示例所示将绑定直接添加到router-outlet You can , however, introduce an "intermediary" service that can communicate the event for you across the router-outlet boundary. 但是,您可以引入“中介”服务,该服务可以跨router-outlet边界为您传达事件。

For Example, you could write some sort of "communication" service as follows: 例如,您可以编写某种“通讯”服务,如下所示:

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

@Injectable()
export class MyCommunicationService {

    constructor() { }

    private emitChangeSource = new Subject<any>();

    changeEmitted$ = this.emitChangeSource.asObservable();

    // Service message
    emitChange(myMessage: any) {
        this.emitChangeSource.next(myMessage);
    }

}

Emit the event from your child component: 从您的子组件发出事件:

...
export class CategoryComponent implements OnInit {
    constructor(private _myCommunicationService: MyCommunicationService) {}

    doSomething(): void {
        ...
        // Emit your event with message
        this._myCommunicationService.emitChange('some change');
    }
...

Then listen for (subscribe to) the event in the parent component (in your case app.component) that contains the router-outlet : 然后在包含router-outlet的父组件(在您的情况下为app.component)中侦听(订阅)该事件:

export class AppComponent implements OnInit {
    constructor(private _myCommunicationService: MyCommunicationService) {

        // Subscribe to the service event
        _myCommunicationService.changeEmitted$.subscribe(myMessage => {
            // TODO: Do what you need to to with the message/value
            ...
        });

    }
}

Let me know if this needs clarification. 让我知道是否需要澄清。 (I could have also totally missed the boat and assumed that the Child Component is loading within the router-outlet when in reality you're doing something entirely different.) (我也可能完全错过了船,并假设子组件正在router-outlet加载,而实际上您正在做的事情完全不同。)

Note: This is untested code. 注意:这是未经测试的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM