Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular4-从父组件调用方法到子模态组件_Angular - Fatal编程技术网

Angular4-从父组件调用方法到子模态组件

Angular4-从父组件调用方法到子模态组件,angular,Angular,我有一个父组件profile-characteristics.component.ts和一个子模式组件pc-prefined-list.component.ts 在父组件模板中更改下拉选项时,我需要在子模式模板中显示其相应的值 子组件方法如下所示 constructor( private utilsService: UtilsService, private route: ActivatedRoute, private _fb: FormBuilder, @In

我有一个父组件profile-characteristics.component.ts和一个子模式组件pc-prefined-list.component.ts

在父组件模板中更改下拉选项时,我需要在子模式模板中显示其相应的值

子组件方法如下所示

 constructor(
    private utilsService: UtilsService,
    private route: ActivatedRoute,
    private _fb: FormBuilder,
    @Inject(DOCUMENT) private document: Document
  ) {}

  ngOnInit() {
    this.pListValueForm = this._fb.group({
      pListValues: this._fb.array([this.initItemRows()]) // here
    });
    //this.setListValues();
    this.route.params.subscribe(params => {
      this.accountId = params['id'];
    });
  }
setListValues() {

    this.pListValueForm = this._fb.group({
      pListValues: this._fb.array([]) // here
    });

    const control = <FormArray>this.pListValueForm.controls['pListValues'];
    this.selectedListValues.forEach(x => {
      control.push(this.patchValue(x.profile_characteristic_list_value_id, x.name, x.sort_order))
    });
  }
this.selectedListValues = [ { "profile_characteristic_list_value_id": "13110afd-f459-11e7-9d12-408d5cbccb60", "profile_characteristic_list_id": "1", "name": "value 2", "sort_order": "2" }, { "profile_characteristic_list_value_id": "13110e5f-f459-11e7-9d12-408d5cbccb60", "name": "value 4", "sort_order": "4", "profile_characteristic_list_id": "2", } ];
}

如果我硬编码这个,模态将正常工作。selectedListValues如下

 constructor(
    private utilsService: UtilsService,
    private route: ActivatedRoute,
    private _fb: FormBuilder,
    @Inject(DOCUMENT) private document: Document
  ) {}

  ngOnInit() {
    this.pListValueForm = this._fb.group({
      pListValues: this._fb.array([this.initItemRows()]) // here
    });
    //this.setListValues();
    this.route.params.subscribe(params => {
      this.accountId = params['id'];
    });
  }
setListValues() {

    this.pListValueForm = this._fb.group({
      pListValues: this._fb.array([]) // here
    });

    const control = <FormArray>this.pListValueForm.controls['pListValues'];
    this.selectedListValues.forEach(x => {
      control.push(this.patchValue(x.profile_characteristic_list_value_id, x.name, x.sort_order))
    });
  }
this.selectedListValues = [ { "profile_characteristic_list_value_id": "13110afd-f459-11e7-9d12-408d5cbccb60", "profile_characteristic_list_id": "1", "name": "value 2", "sort_order": "2" }, { "profile_characteristic_list_value_id": "13110e5f-f459-11e7-9d12-408d5cbccb60", "name": "value 4", "sort_order": "4", "profile_characteristic_list_id": "2", } ];

我需要将selectedListValues从父组件动态传递到子组件。关于如何实现这一点有什么想法吗?

如果这是我的问题,我会在您的子组件中创建一个输入:

@Input() chosenValue: any;
然后将值传递给子级:

<app-pc-predefined-list [chosenValue]="YourParentVariable"></app-pc-predefined-list>

这样,每次更改家长的列表时,您的孩子都会收到通知,并能够启动您的方法来筛选列表中的选项。

您会想到两个选项:

1使子组件成为父组件的一个,允许您从父组件调用子元素函数,并将selectedListValues作为参数传递。如何触发函数调用取决于您

2使用数据绑定。根据列表选择在父组件中定义输出,并发出列表。然后在子组件中实现一个输入,将列表作为属性存储。例如,每次更新父组件中的选择时传递该列表,可能会触发显示该列表的函数。 如果您需要更多的帮助或代码示例,请告诉我,但就长期重要性而言,我非常喜欢边做边学


享受编码乐趣

我已经多次使用此模式,效果非常好

两个组件父组件及其子组件或其他不同组件可以共享其接口支持双向通信的服务

与观察者模式类似,在本例中,服务实例的范围是来自组件发布者和其他组件订阅者的通知

要将复杂数据类型(如selectedListValues)传递给子级,我通常使用一个外部类,该类用其字段表示数据:

model.ts

export class ListValues
{
    public profile_characteristic_list_value_id: string;
    public profile_characteristic_list_id: number;
    public name: string;
    public sort_order: string;
}
mycomponent.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { ListValues} from './model';
@Injectable()
export class MyComponentService{
    // Observable 
    private sampleObservable = new Subject<ListValues>();
    // Observable boolean streams
    sampleSubscriber = this.sampleObservable.asObservable();
    // Event for notification from publisher to subscriber
    sampleEventChanged(value:ListValues)
    {
        this.sampleObservable.next();
    }
}
在要通知所有订阅者其状态更改的组件中:

mycomponent-publisher.ts是您的父组件

  ngAfterViewInit() {
// child is set
this.child.setListValues();
import { Component } from '@angular/core';
import { MyService } from './mycomponent.service';

@Component({
  selector: 'app-my-control-publisher',
  template: `
  <h2>This is the publisher control</h2>
  <button (click)="announce()">Announce to subscriber</button>
  `,
  providers: [MyService]
})

export class MyControlPublisherComponent 
{
  constructor(private myService: MyService) { }

  announce() 
  {
      listValues = new ListValues();
      // here set the info to notify...
      this.myService.sampleEventChanged(listValues);
  }
}
import { Component, OnDestroy } from '@angular/core';
import { MyService } from './mycomponent.service';
import { Subscription } from 'rxjs/Subscription';
import { ListValues} from './model';

@Component({
 selector: 'app-my-control-subscriber',
 template: `
 <h2>This is the subscriber control</h2>
 `,
})

export class MyControlSubscriberComponent 
{
  // Subscriptions
  private componentSubscription: Subscription;

  constructor(private myService: MyService) 
  {
    // Subscription of the notifications
    this.componentSubscription= this.myService.sampleSubscriber.subscribe(value =>
    {
      // Put the code for manage the notification here
      // value is of type 'ListValues'
    }
  }

  ngOnDestroy()
  {
    // Release subscription to avoid memory leaks when the component is destroyed
    this.componentSubscription.unsubscribe();
  }
}
在订阅服务器组件中,要获取通知的用户

mycomponent-subscriber.ts是您的子组件

  ngAfterViewInit() {
// child is set
this.child.setListValues();
import { Component } from '@angular/core';
import { MyService } from './mycomponent.service';

@Component({
  selector: 'app-my-control-publisher',
  template: `
  <h2>This is the publisher control</h2>
  <button (click)="announce()">Announce to subscriber</button>
  `,
  providers: [MyService]
})

export class MyControlPublisherComponent 
{
  constructor(private myService: MyService) { }

  announce() 
  {
      listValues = new ListValues();
      // here set the info to notify...
      this.myService.sampleEventChanged(listValues);
  }
}
import { Component, OnDestroy } from '@angular/core';
import { MyService } from './mycomponent.service';
import { Subscription } from 'rxjs/Subscription';
import { ListValues} from './model';

@Component({
 selector: 'app-my-control-subscriber',
 template: `
 <h2>This is the subscriber control</h2>
 `,
})

export class MyControlSubscriberComponent 
{
  // Subscriptions
  private componentSubscription: Subscription;

  constructor(private myService: MyService) 
  {
    // Subscription of the notifications
    this.componentSubscription= this.myService.sampleSubscriber.subscribe(value =>
    {
      // Put the code for manage the notification here
      // value is of type 'ListValues'
    }
  }

  ngOnDestroy()
  {
    // Release subscription to avoid memory leaks when the component is destroyed
    this.componentSubscription.unsubscribe();
  }
}

如果下拉值发生更改,则此操作非常有效。但还有另一个问题。考虑到页面加载时,下拉值没有改变,并且当单击父组件中的按钮时,仍然需要在模式上显示相应的值。因为我使用了ngonchanges,所以我不确定如何反映子组件上的更改。对此有何想法?OnChanges是一个生命周期挂钩,这意味着即使在加载页面时也会调用它。如果不是,出于X或Y的原因,您可以简单地模拟单击按钮来触发它。