Angular 自动将子零部件数据更改发送到父零部件

Angular 自动将子零部件数据更改发送到父零部件,angular,angular2-template,angular2-components,Angular,Angular2 Template,Angular2 Components,我有BusinessComponent(父项)和AddressComponent(子项)。现在在AddressComponent中,双向数据绑定工作正常。现在,我需要将AddressComponent中的任何更改作为Address对象发送到BusinessComponent,而不是Address对象的单个属性。我试着使用ngOnChanges(),但代码说明了这一点 Angular仅在输入属性的值更改时调用钩子。hero属性的值是对hero对象的引用。Angular不在乎英雄自己的名字属性改变。

我有
BusinessComponent
(父项)和
AddressComponent
(子项)。现在在
AddressComponent
中,双向数据绑定工作正常。现在,我需要将
AddressComponent
中的任何更改作为
Address
对象发送到
BusinessComponent
,而不是
Address
对象的单个属性。我试着使用
ngOnChanges()
,但代码说明了这一点

Angular仅在输入属性的值更改时调用钩子。hero属性的值是对hero对象的引用。Angular不在乎英雄自己的名字属性改变。英雄对象引用没有更改,因此,从Angular的角度来看,报告没有更改

在不发送数据的情况下,父级正在检测
AddressComponent
的变化。我找不到实现这一目标的方法

这是我的代码示例

地址组件

import { Component,  EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';
import { AppService } from '../services';
import { Address } from '../types';

@Component({
  selector: 'app-address',
  templateUrl: 'address.component.html'
})

export class AddressComponent implements OnInit, OnChanges {

    @Input()
    address: Address;

    @Output()
    addressChange: EventEmitter<Address> = new EventEmitter<Address>();

    constructor(
        private appService: AppService
    ) { super(appService); }

  ngOnInit() {
        this.address = new Address('');
  }
    ngOnChanges(changes: SimpleChanges) {
        // This is not being called for emitting the changes.
        console.log(changes);
        this.addressChange.emit(this.address);
    }
}
import{Component,EventEmitter,Input,OnInit,Output,OnChanges,SimpleChanges}来自“@angular/core”;
从“../services”导入{AppService};
从“../types”导入{Address};
@组成部分({
选择器:“应用程序地址”,
templateUrl:'address.component.html'
})
导出类AddressComponent实现OnInit、OnChanges{
@输入()
地址:地址;
@输出()
addressChange:EventEmitter=新的EventEmitter();
建造师(
专用appService:appService
){super(appService);}
恩戈尼尼特(){
this.address=新地址(“”);
}
ngOnChanges(更改:SimpleChanges){
//发出更改时不会调用此命令。
控制台日志(更改);
this.addressChange.emit(this.address);
}
}
地址组件模板

<div class="form-row">
     <label class="form-label" for="houseNo">{{ labels['houseNo'] }}</label>
    {{ address.houseNo }}
    <input [(ngModel)] = "address.houseNo" type="text" name="houseNo" id="houseNo" ref-houseNo>
</div>

<div class="form-row">
     <label class="form-label"  for="street">{{ labels['street'] }}</label>
    <input [(ngModel)] = "address.street" type="text" name="street" id="street" ref-street>
</div>

<div class="form-row">
     <label class="form-label"  for="village">{{ labels['village'] }}</label>
    <input [(ngModel)] = "address.village" type="text" name="village" id="village" ref-village>
</div>

<div class="form-row">
     <label class="form-label"  for="city">{{ labels['city'] }}</label>
    <input [(ngModel)] = "address.city" type="text" name="city" id="city" ref-city>
</div>

{{标签['houseNo']}
{{address.houseNo}
{{标签['street']}
{{标签['village']}
{{labels['city']}
我在
BusinessComponet


如何实现这一点?

如评论中所述,您不需要双向绑定或
@Output
。由于JS对象是可变的,这意味着引用是同一个对象,但是,您正在这样做

ngOnInit() {
  this.address = new Address('');
}
在child中,我也不理解这个初始化,因为
Address
(我假设它是一个类)有几个属性。但是如果你想有相同的参考,你不应该这样做

我建议您对您的
地址使用界面,类似于:

export interface Address {
  houseNo: number;
  street: string;
  village: string;
  city: string;
}
然后还可以键入对象,如:

address: Address = {}
在父对象中,或者将初始值设置为,但似乎希望在子对象中有一个干净的对象

因此,从child
OnInit
中删除以下内容,您就可以开始了:)


您的地址变量是如何更改的??它将由用户更改。添加了模板。您的代码似乎是正确的。您不需要向父组件发出任何事件,因为父组件和子组件使用相同的对象引用。只需从模板中删除括号,修改子组件上的数据,您就会看到它也会在父组件上被修改。而且您对ngOnChanges方法有误解。当从组件外部(从父组件)修改任何@Input()变量时,将触发ngOnChanges。它不会在组件中调用,因为您只更改对象的属性,而不是对象本身!不,它能用:)你能看看这个小玩意儿吗。我刚刚添加了一个没有任何成员的新类和扩展的应用程序组件。它打破了一切。我这样做的原因是,我的父级扩展了一个类,如果我没有在child中初始化地址,我将得到未定义的错误。这是一个非常少的信息,意味着这个空类
Subscr
,不知道它是用来做什么的。由于plunker中的类是空的,所以我也不能对plunker做太多…:(据我所知,这可能是使用共享服务,而不是使用
@Input()
。但正如前面所说,很难用这些信息来判断。不幸的是,我无法在plunker中复制该问题。一旦我获得足够的声誉,我会投票给你的答案。除非你在plunker中重新创建该问题,否则帮不上忙。因为我看不到其余的代码。但我们可以再尝试一件事……如果错误是thr由于异步问题而拥有?我们可以利用
输入
ngOnChanges
。如果我使用了布尔标志
show
ngOnChanges
,请检查此插件:如果这不起作用,很可能是共享服务:)
this.address = new Address('');