angular 5 从父组件设置子组件属性
Posted
技术标签:
【中文标题】angular 5 从父组件设置子组件属性【英文标题】:angular 5 setting child component property from parent component 【发布时间】:2019-05-05 13:15:38 【问题描述】:我想从父组件设置子组件属性
parent.component.html
<div>
<child-detail #myCarousel [childList]="detail.List" ></child-detail>
</div>
parent.component.ts
@Component(
selector: "parent",
templateUrl: "./parent.component.html",
)
export class AppComponent
public detail; // it is of JSON type
child.component.ts
@component(
selector:'child-detail',
templateUrl: './child.component.html'
)
export class ChildDetailComponent
@Input() public childList; // that list of array type
child.component.html
<div *ngFor = "let list of childList">
<li>list </li>
</div>
我知道我可以通过@Input()
绑定设置此属性,但这只会在组件初始化时设置,我想在某个时候以编程方式在中间设置它。
我知道我可以使用
访问父级中的这个子属性@ViewChild(ChildDetailComponent) childDetailComponent: ChildDetailComponent;
console.log(this.childDetailComponent.childList);
但我想在任何父母事件中以编程方式设置它。
【问题讨论】:
那么为什么不能使用input
属性并在父事件上填充该输入属性?
*但这只会在组件初始化时设置 *??这不是真的。每当您更改父项中的道具时,都会设置它。阅读ngOnChanges()
钩子
@xyz 你能详细说明一下吗?
当父组件中childList
的值发生变化时,childComponent中的childList的值也将被更新,但是如果你去更改父组件中childList
的值childList
的值在子组件中发生变化,您可以对childList
使用set 方法Input
只是一个注释。您正在使用 TypeScript。 TypeScript 有类型。那么为什么不使用// that list of array type
,而是正确声明变量的类型呢?
【参考方案1】:
如果不使用 @Input
属性,我不确定您是如何做到的。
每当您传递给它的输入发生变化时,它也会反映在子组件中。您可以在子组件中的ngOnChanges
中跟踪它。试试log
ging 到console
试试这个:
import Component from '@angular/core';
@Component(
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
)
export class AppComponent
detail: any =
childList: []
;
setChildList()
this.detail.childList = [
id: 1, name: 'John' ,
...
];
在模板中:
<button (click)="setChildList()">Set Child List</button>
<hello [childList]="detail.childList"></hello>
这里@Input
属性在单击按钮时发生变化。但在您的情况下,您可以简单地将 setChildList
方法称为您的事件。
这里有一个Working Sample StackBlitz 供您参考。
【讨论】:
但是 ngOnChanges() 只检测到主要类型的变化,所以这个生命周期钩子会运行,但是如果对象属性发生变化,它就不会运行。 从您所说的来看,您的组件上似乎有一个ChangeDetectionStrategy
或 OnPush
。在这种情况下,它只会在 @Input
对象的引用发生变化时运行。
在这种情况下,您所说的没有任何意义。我正在将输入传递给子组件,就像您想要的那样。如果您查看我的 StackBlitz 示例,它会按预期传递值并在子组件中更新它。
您可以查看以下网址concretepage.com/angular-2/…。 (如果对象属性发生变化,此技术将不起作用)
您是否检查过 StackBlitz 示例?将对象作为@Input
传递正是我在那里所做的。它正在检测更改并更新子组件以及视图。【参考方案2】:
您可以务实地使用服务来共享数据。
第 1 步:创建数据共享服务。
import Injectable from '@angular/core';
import BehaviorSubject from 'rxjs';
@Injectable()
export class DataService
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor()
changeMessage(message: string)
this.messageSource.next(message)
第 2 步:更改消息
export class ParentComponent implements OnInit
message:string;
constructor(private data: DataService)
ngOnInit()
this.data.changeMessage("Hello from Sibling")
第 3 步:获取消息
export class ChildComponent implements OnInit
message:string;
constructor(private data: DataService)
ngOnInit()
this.data.currentMessage.subscribe(message => this.message = message)
【讨论】:
您应该在 app.module.ts 中的providers: [DataService]
添加DataService,否则会出现以下错误NullInjectorError: No provider for DataService!
。【参考方案3】:
在子组件中使用@input
。可以使用ngOnChanges
监听子组件的变化。
@Input() name: string;
ngOnChanges(changes: SimpleChanges)
const name: SimpleChange = changes.name;
console.log('prev value: ', name.previousValue);
console.log('got name: ', name.currentValue);
工作stackblitz
【讨论】:
以上是关于angular 5 从父组件设置子组件属性的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Angular 5 中的点击数据从父组件传递到子组件?