【问题标题】:Angular @Input in child component also updates value in parent component子组件中的 Angular @Input 也会更新父组件中的值
【发布时间】:2019-07-20 09:18:11
【问题描述】:

属性上的@Input 结合[propertyNameInParent] = ”propertyNameInChild” 允许我们将父属性的值绑定到子属性。也称为单向绑定。奇怪的是,就我而言,它也在更新父类中的属性。这怎么可能?

父组件 -> 最喜欢的城市 子组件 -> city-detail

所以基本上在(点击)事件中,最喜欢的城市是选择(selectedCity 属性)。然后在城市详情组件中,城市可以通过点击onPlusIconClick()获得点赞。不知何故,这也触发了最喜欢城市中的 city.rating 上升。为什么我不必使用事件发射器将更新后的值发送回父组件?

favorite-cities.component.ts

import {Component, OnInit} from '@angular/core';
import {CitiesService} from '../../services/cities.service';
import {City} from '../../model/city';

@Component({
selector: 'app-favorite-cities',
templateUrl: './favorite-cities.component.html',
styleUrls: ['./favorite-cities.component.css']
})
export class FavoriteCitiesComponent implements OnInit {

cities: City[];
selectedCity: City;

constructor(private citiesService: CitiesService) {
}

ngOnInit() {
    this.citiesService.getCities().subscribe(
        (data) => this.cities = data,
        (err) => console.log(err),
        () => { }
    );
}

setSelectedCity(city: City): void {
    this.selectedCity = city;
}

}

favorite-cities.component.html

<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="col-4">
            <h2>Mijn favoriete steden zijn: </h2>
            <ul class="list-group" *ngFor="let city of cities">
                <li class="list-group-item" (click)="setSelectedCity(city)">{{city.id}} - {{city.name}}
                    <span class="float-right badge badge-success">Likes {{city.rating}} .   </span>
                </li>
            </ul>
        </div>
        <div class="col-4">
            <app-city-detail [selectedCity]="selectedCity"></app-city-detail>
        </div>
    </div>
</div>

city-detail.component.ts

import {Component, Input, OnInit} from '@angular/core';
import {City} from '../../model/city';
import {CitiesService} from '../../services/cities.service';

@Component({
selector: 'app-city-detail',
templateUrl: './city-detail.component.html',
styleUrls: ['./city-detail.component.css']
})
export class CityDetailComponent implements OnInit {

@Input()
selectedCity: City;

constructor(private citiesService: CitiesService) {
}

ngOnInit() {
}

onMinusIconClick(): void {
    if (this.selectedCity.rating > 0) {
        this.selectedCity.rating -= 1;
    }
    this.citiesService.updateRatingOfCity(this.selectedCity).subscribe(
        (data) => { console.log('oaksdoaks'); },
    );

}

onPlusIconClick(): void {
    this.selectedCity.rating += 1;
    this.citiesService.updateRatingOfCity(this.selectedCity).subscribe();
}
}

city-detail.component.html

<div *ngIf="selectedCity">
<div class="container-fluid">
    <div class="row">
        <h2>City details</h2>
        <div class="col-1">
            <i (click)="onPlusIconClick()" class="fas fa-2x fa-plus-square"></i>
        </div>
        <div class="col-1">
            <i (click)="onMinusIconClick()" class="fas fa-2x fa-minus-square"></i>
        </div>
    </div>
</div>
<ul class="list-group">
    <li class="list-group-item">Naam: {{selectedCity.id}} </li>
    <li class="list-group-item">Provincie: {{selectedCity.provincie}}</li>
    <li class="list-group-item">Highlights: {{selectedCity.highlights}} </li>
</ul>
<img class="img-fluid" src="assets/img/{{selectedCity.name.trim()}}.jpg" >

【问题讨论】:

    标签: angular property-binding


    【解决方案1】:

    因为您正在输入一个对象,而这只是一个reference。所以父母和孩子都有一个引用完全相同的对象的属性。

    如果这是不受欢迎的行为,您必须在设置所选城市时创建浅表副本。或者在您更新的任何其他地方.. 有很多选择:

    setSelectedCity(city: City): void {
      this.selectedCity = { ...city }; //shallow copy
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-03
      • 2017-11-23
      • 2021-02-10
      • 2020-01-02
      • 2021-02-23
      • 2018-07-15
      • 1970-01-01
      • 2019-03-15
      • 2018-09-14
      相关资源
      最近更新 更多