передать объект от родителя к дочернему

avatar
Aymen Kanzari
8 апреля 2018 в 11:24
1306
3
0

У меня есть объект соглашения, который я должен передать в качестве входных данных для дочернего компонента, идентификатор соглашения отображается, когда я вызываю его в дочернем шаблоне, но я получаю неопределенность, когда пытаюсь использовать свое соглашение в консоли. .журнал. Я попытался поместить свой console.log в конструктор дочернего элемента, а также в ngOnInit, ngAfterViewInit и ngOnChanges. Для ngOnChanges, когда я передаю только идентификатор соглашения в качестве входных данных для дочернего компонента, он работает нормально, но мне нужно передать соглашение, а не его идентификатор.

index.component.ts

@Component({
    templateUrl: './index.template.html',
    selector: 'be-convention-update',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class ConventionUpdateComponent {

    private convention$: Convention;
    private conventionId: number;

    constructor(private route: ActivatedRoute,
        private conventionService: ConventionService) {
        this.route.params.subscribe(
            (params: any) => {
                this.conventionId = params['id'];
                this.conventionService.getOne(this.conventionId).subscribe(response => this.convention$ = response);
            }
        );
    }

}

index.template.html

<be-form-convention [convention]="convention$"></be-form-convention>

form.component.ts

@Component({
    selector: 'be-form-convention',
    templateUrl: './form.template.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class ConventionFormComponent implements OnChanges, OnInit {

    @Input() convention: Convention;

    constructor() {
    }

    public ngAfterViewInit() {
      console.log(this.convention); //undefined
    }

    public ngOnInit(): void {
      console.log(this.convention); //undefined
    }

    public ngOnChanges(changes: SimpleChanges): void {
      const object: SimpleChange = changes.convention;
      console.log('prev value: ', object.previousValue); //undefined
      console.log('got name: ', object.currentValue); //undefined
    }

}
Источник
Orodan
8 апреля 2018 в 11:29
1

Вы действительно получаете свой объект соглашения от вас ConventionService.getOne ?

Aluan Haddad
8 апреля 2018 в 11:34
0

Суффикс $ кричит о наблюдаемом и «нуждается в асинхронном канале», но, по меньшей мере, неясно, что вы делаете и почему вы это делаете.

Aymen Kanzari
8 апреля 2018 в 11:50
0

@Orodan да, я получаю объект соглашения от своего сервиса

Aymen Kanzari
8 апреля 2018 в 11:51
0

@AluanHaddad, ты прав, но это не связано с моей проблемой

Orodan
8 апреля 2018 в 13:14
0

Из того, что я вижу здесь, вы все делаете правильно, можете ли вы показать свой шаблон ConventionUpdateComponent и модель Convention, пожалуйста?

Aymen Kanzari
8 апреля 2018 в 16:21
0

@Ородан, я изменяю свой вопрос

Ответы (3)

avatar
Jatinder Kumar
8 апреля 2018 в 11:42
0

Насколько я понимаю, вы хотите выполнить некоторую операцию, когда вы получаете вход или изменения входного значения.

Вы можете использовать директиву ввода с функцией set, как показано ниже:

_convention: Convention;
@Input()
set convention(convention: Convention) {
    this._convention = convention;
    //the code you want to handle after input is received
}
Aymen Kanzari
8 апреля 2018 в 12:06
0

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

Jatinder Kumar
8 апреля 2018 в 17:10
0

Проблема в этом случае может заключаться в том, что значение передается по ссылке. Таким образом, изменения в объекте иногда не вызывают никаких событий в дочернем компоненте. Но он получает значение, потому что ссылочная переменная такая же. Таким образом, вы можете отправить текст, передав новую ссылку на объект с тем же значением. Вы также можете попробовать передать объект типа any вместо соглашения и передать входное значение как JSON.parse(JSON.stringify(objectvariable)); это создаст новую переменную, поэтому ваш дочерний компонент должен реагировать на изменения.

Aymen Kanzari
8 апреля 2018 в 18:34
0

что вы имеете в виду передать входное значение как JSON.parse(JSON.stringify(objectvariable));

Jatinder Kumar
8 апреля 2018 в 18:42
0

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

avatar
Vikas
8 апреля 2018 в 14:34
1

Поскольку это асинхронная операция, я предлагаю вам подождать, пока соглашение не получит значение, использующее *ngIf для загрузки дочернего компонента, когда объект соглашения не пуст

<ng-container *ngIf="convention$">
<be-form-convention [convention]="convention$"></be-form-convention>
</ng-container>
Vikas
8 апреля 2018 в 17:10
0

@ Аймен Канзари, ты пробовал это?

Aymen Kanzari
8 апреля 2018 в 19:07
0

Да, когда я пробовал, html дочернего компонента (ConventionFormComponent) не отображался

Vikas
8 апреля 2018 в 19:12
0

это означает, что ваш объект всегда пуст? что вы делаете, когда делаете console.log(this.convention$) внутри подписки

Aymen Kanzari
8 апреля 2018 в 19:20
0

он не пустой, он отображает данные в консоли, когда я делаю console.log(this.convention$) внутри подписки

Vikas
8 апреля 2018 в 19:23
0

создать plunker или stackblitz

avatar
kartik chawla
8 апреля 2018 в 12:18
-2

Для связи между компонентами я всегда использую службу.

Что я делаю: я создаю службу и делаю две функции (getData и setData).

когда я хочу отправить некоторые данные из одного компонента в другой, я вызываю метод setData, а когда я хочу получить данные в другом компоненте, я использую метод getData.

Вот пример:

импорт {Injectable} из '@angular/core';

@Injectable()
export class DataExchange {

  data; //Global Variable of 'any' type.

  setData(data){
this.data = data;
  }

getData():any{
  return this.data;
}
}