Angular 9 - Свойства ввода типа массива Изменить на обоих компонентах? - PullRequest
0 голосов
/ 20 апреля 2020

Я столкнулся с проблемой, которую я хочу убедиться, что это правда. Я написал небольшое приложение Angular, чтобы показать, о чем я говорю.

Когда я передаю массив (любой [] или объект []) дочернему компоненту как свойство @Input и изменяю значение в дочернем элементе, почему изменения отражаются в родительском элементе? Из того, что я прочитал из документации, предполагается, что это односторонняя привязка, что означает, что мне нужно будет использовать свойство @Output (EventEmitter) от дочернего элемента, чтобы отправить изменения обратно родителю.

Я привел код в качестве примера того, что я объясняю, возможно, слишком широко. Код имеет два свойства, которые он отправляет дочернему компоненту: одно представляет собой массив объектов, а другое - строку в виде простого текста. Я использую поле ввода, чтобы изменить значение Name1 и текстовое значение.

Итак, мой вопрос: почему при внесении изменений в массив данных изменения отражаются в родительском элементе, а когда я изменяю текстовую строку, это не так? Есть ли где-то в документации, что объясняет это, или кто-то может объяснить, почему это так?

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  arr = [
    {name: 'Name1', data: 'This is data 1..'},
    {name: 'Name2', data: 'This is data 2..'},
    {name: 'Name3', data: 'This is data 3..'},
  ];

  someText = 'This is text';
}

app.component. html

<div style="border: 1px solid grey; padding: 4px;">
  <h4>Parent</h4>
  <ul>
    <li *ngFor="let item of arr">Name: {{ item['name'] }}, Data: {{ item['data'] }}</li>
  </ul>
  <strong>{{ someText }}</strong>
</div>
<child-component [arr]="arr" [someText]="someText"></child-component>

child-component.component.ts

import {Component,  Input} from '@angular/core';

@Component({
  selector: 'child-component',
  templateUrl: './child-component.component.html',
  styleUrls: []
})
export class ChildComponentComponent {

  @Input() arr: any[];
  @Input() someText: string;

  sendChanges(changes: any) {
    this.arr[0]['name'] = changes;
    this.someText = changes;
  }
}

child-component.component. html

<div style="border: 1px solid grey; padding: 4px;">
  <h4>Child</h4>
  <ul>
    <li *ngFor="let item of arr">Name: {{ item['name'] }}, Data: {{ item['data'] }}</li>
  </ul>
  <div><strong>{{ someText }}</strong></div>

  <input type="text" #changes>
  <button (click)="sendChanges(changes.value)">Send Changes</button>
</div>

Отображение данных изображения Без Изменения

Image Displaying Data Without Changes

Отображение данных изображения С Изменения

Image Displaying Data With the Changes

1 Ответ

1 голос
/ 20 апреля 2020

Это что-то, связанное с javaScript / typeScript, а не Angular

Объекты и массивы передаются по ссылке, поэтому, если вы обновите массив где-то, он будет обновлен в другом месте

вы можете передать копию массива вместо того, чтобы передавать сам массив

мы можем использовать что-то вроде этого, чтобы получить копию из объекта или массива

let snapshotOfMyArray = JSON.parse(JSON.stringify(myArray));

, чтобы мы могли это сделать в шаблоне компонента приложения

<div style="border: 1px solid grey; padding: 4px;">
  <h4>Parent</h4>
  <ul>
    <li *ngFor="let item of arr">Name: {{ item['name'] }}, Data: {{ item['data'] }}</li>
  </ul>
  <strong>{{ someText }}</strong>
</div>
<child-component [arr]="JSON.parse(JSON.stringify(arr))" [someText]="someText"></child-component>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...