angular4中子组件改变值不会影响父组件

问题描述

https://www.angular.cn 中 父组件传值到子组件用单向绑定,此时例子中只是用了@input,并没有用@output,但是我修改子组件里面的input里的值时,却同时将父组件中的指定的li元素的值也修改了,此时应该怎样避免父组件值被修改

相关代码

父组件ts:
import { Component, OnInit } from '@angular/core';
import {HEROES} from '../mock-data';

@Component({
selector: 'app-show-value',
templateUrl: './show-value.component.html',
styleUrls: ['./show-value.component.css']
})
export class ShowValueComponent implements OnInit {
para: Hhh = { //在oninit里面只能先对象继承然后再对象赋值,对象声明要在oninit外用构造函数进行

id: 1,
name: 'ww'

}
ok: string;
heros = HEROES;//列表的mockdata
selectedHero: Hhh;

constructor() {

}

ngOnInit() {

this.ok = 'ss';

}
onselect(hero2: Hhh): void {

this.selectedHero = hero2;

}
}

export class Hhh {
id: number;
name: string;
}

///////////////////////////////////////////////////////////////////////////
父组件的html
<div class = "showValue">
组件id号:{{para.id}}
组件名字:{{para.name|uppercase}}
<input type="text" [(ngModel)] = "para.name" placeholder="name">
<ul class="herosStyle">

<li *ngFor="let herolist of heros" (click)="onselect(herolist)">
  <span>{{herolist.name}}</span>
</li>

</ul>

</div>

<app-show-value-detail [hero2]="selectedHero"></app-show-value-detail>
///////////////////////////////////////////////////////////////////////////

子组件html:
<div *ngIf="hero2">
<div>被选中的名字是:{{hero2.name|uppercase}}</div>
<!--<input [(ngModel)]="hero2.name" placeholder="name">-->
</div>
///////////////////////////////////////////////////////////////////////////

子组件ts:
import {Component, Input, OnInit} from '@angular/core';
// import {Hhh} from '../show-value/show-value.component';

@Component({
selector: 'app-show-value-detail',
templateUrl: './show-value-detail.component.html',
styleUrls: ['./show-value-detail.component.css']
})
export class ShowValueDetailComponent implements OnInit {
@Input()
private hero2: Hhh2;

constructor() { }

ngOnInit() {

setInterval(() => {
  this.hero2.name = 'sss';
});

}

}
export class Hhh2 {
id: number;
name: string;
}

阅读 4.1k
1 个回答

你这个不是outputinput的问题, 问题的根源是引用值原始值的问题

@Input()
private hero2: Hhh2;

hero2是个对象,对象在js中是引用值, 所以你在子组件中修改了hero2,父组件中的值当然就改变了,因为都指向同一个内存地址。

你可以尝试传入的值是一个string, number, boolean 这种原始值, 你再试试, 你就能理解了。

以下是原始值和引用值的基础知识

在ECMAscript中,变量可以存放两种类型的值,即原始值和引用值
原始值指的是代表原始数据类型的值,也叫基本数据类型,包括:Number、Stirng、Boolean、Null、Underfined
引用值指的是复合数据类型的值,包括:Object、Function、Array、Date、RegExp
根据数据类型不同,有的变量储存在栈中,有的储存在堆中。具体区别如下:
原始变量及他们的值储存在栈中,当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始变量互不影响。
引用值是把 引用变量的名称储存在栈中,但是把其实际对象储存在堆中,且存在一个指针由变量名指向储存在堆中的实际对象,当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针,此时 两者指向的 是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不是通过方法 而是通过 重新赋值 此时 相当于 重新开了一个房间 该值的原指针改变 ,则另外一个 值 不会随他的改变而改变。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进