Typescript 访问父组件中的属性
我在顶级组件中有一个属性,该属性使用来自HTTP源的数据,例如(这在名为Typescript 访问父组件中的属性,typescript,angular,Typescript,Angular,我在顶级组件中有一个属性,该属性使用来自HTTP源的数据,例如(这在名为app.ts)的文件中): 现在在Angular 1.x中,这将很容易,因为我可以在我的子控制器中引用$parent,或者(反模式警报!!!)我会愚蠢地将这些数据放在$rootScope中 在Angular 2中访问父级的最佳方式是什么?有不同的方式: 全球服务 另见 父级共享并注入子级的服务 类似于全球服务,但列在父级的提供者或视图提供者中,而不是boostrap(…),并且仅对父级的子级可用 父项注入子项
app.ts
)的文件中):
现在在Angular 1.x中,这将很容易,因为我可以在我的子控制器中引用$parent
,或者(反模式警报!!!)我会愚蠢地将这些数据放在$rootScope
中
在Angular 2中访问父级的最佳方式是什么?有不同的方式:
- 全球服务
- 另见
- 父级共享并注入子级的服务
- 类似于全球服务,但列在父级的
或提供者
中,而不是视图提供者
,并且仅对父级的子级可用boostrap(…)
- 类似于全球服务,但列在父级的
- 父项注入子项并由子项直接访问
- 缺点:紧耦合
- 数据绑定
导出类配置文件实现OnInit{
@Input()userStatus:userStatus;
...
}
您可以:
- 为子组件定义
参数,并在从父组件使用此组件时提供值:userStatus
@Component({ (...) }) export class Profile implements OnInit { @Input() userStatus:UserStatus; (...) }
在家长中:<profile [userStatus]="userStatus"></profile>
@Component({ (...) }) export class Profile implements OnInit { @Input() userStatus:UserStatus; (...) }
注意它们之间的循环依赖关系<profile [userStatus]="userStatus"></profile>
- 我也遇到了同样的问题,但解决方法不同。我不知道这是否是一个好的方法,但它对我所需要的非常有效
我在子组件的构造函数上使用了@Inject,如下所示:
import { Component, OnInit, Inject } from '@angular/core';
import { ParentComponent } from '../views/parent/parent.component';
export class ChildComponent{
constructor(@Inject(ParentComponent) private parent: ParentComponent){
}
someMethod(){
this.parent.aPublicProperty = 2;
}
}
这对我来说很有效,您只需要将要调用的方法或属性声明为public
在我的例子中,AppComponent处理路由,我使用菜单项中的徽章提醒用户新的未读消息可用。因此,每当用户读取消息时,我希望计数器刷新,因此我调用refresh方法,以便菜单nav上的数字用新值更新。这可能不是最好的方法,但我喜欢它的简单性。我制作了一个通用组件,需要引用使用它的父组件。以下是我的想法: 在我的组件中,我输入了@Input:
@Input()
家长:任何;
然后在使用此组件的父级中:
@Component({
(...)
})
export class Profile implements OnInit {
constructor(app:App) {
this.userStatus = app.userStatus;
}
(...)
}
在超级组件中,我可以使用来自父级的任何公共内容:
@Component({
(...)
})
export class Profile implements OnInit {
@Input()
userStatus:UserStatus;
(...)
}
<profile [userStatus]="userStatus"></profile>
属性:
parent.anyAttribute
职能:
parent[myFunction](anyParameter)
当然,私有内容将无法访问。在Angular 6上,我通过构造函数注入父属性来访问父属性。不是最好的解决方案,但它很有效:
constructor(@Optional() public parentComponentInjectionObject: ParentComponent){
// And access like this:
parentComponentInjectionObject.thePropertyYouWantToAccess;
}
因为亲子互动不是一件容易的事情。但是,通过在子组件中引用父组件,可以更容易地进行交互。在我的方法中,首先需要通过调用子组件的函数来传递父组件的引用。下面是此方法的示例 子组件的代码
import { Component, Input,ElementRef,Renderer2 } from '@angular/core';
import { ParentComponent } from './parent.component';
@Component({
selector: 'qb-child',
template: `<div class="child"><button (click)="parentClickFun()">Show text Of Parent Element</button><button (click)="childClickFun()">Show text Of Child Element</button><ng-content></ng-content></div>`,
styleUrls: ['./app.component.css']
})
export class ChildComponent {
constructor(private el: ElementRef,private rend: Renderer2){
};
qbParent:ParentComponent;
getParent(parentEl):void{
this.qbParent=parentEl;
console.log(this.el.nativeElement.innerText);
}
@Input() name: string;
childClickFun():void{
console.log("Properties of Child Component is Accessed");
}
parentClickFun():void{
this.qbParent.callFun();
}
}
从'@angular/core'导入{Component,Input,ElementRef,Renderer2};
从“./parent.component”导入{ParentComponent};
@组成部分({
选择器:“qb子对象”,
模板:`Show text Of Parent Element Show text Of Child Element`,
样式URL:['./app.component.css']
})
导出类子组件{
构造函数(专用el:ElementRef,专用rend:Render2){
};
qb父母:父母成分;
getParent(parentEl):无效{
this.qbParent=parentEl;
log(this.el.nativeElement.innerText);
}
@Input()名称:string;
childClickFun():无效{
log(“访问子组件的属性”);
}
parentClickFun():无效{
this.qbParent.callFun();
}
}
这是父组件的代码
import { Component, Input , AfterViewInit,ContentChild,ElementRef,Renderer2} from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'qb-parent',
template: `<div class="parent"><ng-content></ng-content></div>`,
styleUrls: ['./app.component.css']
})
export class ParentComponent implements AfterViewInit {
constructor(private el: ElementRef,private rend: Renderer2){
};
@Input() name: string;
@ContentChild(ChildComponent,{read:ChildComponent,static:true}) qbChild:ChildComponent;
ngAfterViewInit():void{
this.qbChild.getParent(this);
}
callFun():void{
console.log("Properties of Parent Component is Accessed");
}
}
import{Component,Input,AfterViewInit,ContentChild,ElementRef,Renderer2}来自'@angular/core';
从“./child.component”导入{ChildComponent};
@组成部分({
选择器:“qb父项”,
模板:``,
样式URL:['./app.component.css']
})
导出类ParentComponent实现AfterViewInit{
构造函数(专用el:ElementRef,专用rend:Render2){
};
@Input()名称:string;
@ContentChild(ChildComponent,{read:ChildComponent,static:true})qbChild:ChildComponent;
ngAfterViewInit():void{
this.qbChild.getParent(this);
}
callFun():void{
log(“访问父组件的属性”);
}
}
Html代码
<qb-parent>
This is Parent
<qb-child>
This is Child
</qb-child>
</qb-parent>
这是家长
这是我的孩子
在这里,我们通过调用子组件的函数来传递父组件。
下面的链接是此方法的一个示例。
点击 Angular2非常注重性能。Angular2正在(或将要——还有很多工作要做)进行优化,以便即使是大型应用程序也能表现良好。此外,对TS和Dart的支持(它们比JS更适合大型应用程序)带来了一些样板和限制,但这也允许分析代码并进行更智能的优化。没有阴影就没有光明…@GünterZöchbauer,我很高兴你指出了
@输入
的“缺点:紧密耦合”,但我希望你承认使用服务的缺点——即与Angular的依赖注入系统的便利性有关。读者应意识到,具有高链接度,即扇出/入,同样危险。使用直接输入链接,您至少遵守LoD(德米特定律),但我会为每个模块设计一个沙箱或控制器/门面,这样它们就不会分散到大量服务中;因为那是你真正需要的时候。当然紧耦合问题是关于@Host()父:App
,而不是使用@Input()
?注意:如果你需要@Host()是可选的,你的代码必须是@optional@Ho>