typescript - tutorial - install angular 2
Acceder a una propiedad en un componente primario (6)
Dado que la interacción padre-hijo no es una tarea fácil de hacer. Pero al tener una referencia para el componente principal en el componente secundario, sería mucho más fácil interactuar. En mi método, primero debe pasar una referencia del componente primario llamando a la función del componente secundario. Aquí está el de este método.
El código para el componente hijo.
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();
}
}
Este es el código para el componente principal
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");
}
}
El código html
<qb-parent>
This is Parent
<qb-child>
This is Child
</qb-child>
</qb-parent>
Aquí pasamos el componente padre llamando a una función del componente hijo. El siguiente enlace es un ejemplo de este método. Haga clic here !
Tengo una propiedad en un Componente de nivel superior que utiliza datos de una fuente HTTP como esta (esto está en un archivo llamado
app.ts
):
import {UserData} from ''./services/user-data/UserData'';
Component({
selector: ''app'', // <app></app>
providers: [...FORM_PROVIDERS],
directives: [...ROUTER_DIRECTIVES],
pipes: [],
template: require(''./app.html'')
})
@RouteConfig([
// stuff here
])
export class App {
// Please note that UserData is an Injectable Service I have written
userStatus: UserStatus;
constructor(private userData: UserData) {
this.userStatus = new UserStatus();
}
ngOnInit() {
this.userData.getUserStatus()
.subscribe(
(status) => {
this.userStatus = status; // I want to access this in my Child Components...
},
(err) => {console.log(err);},
() => {console.log("User status complete"); }
);
}
}
Ahora, tengo otro Componente que es un hijo directo del Componente de nivel superior y dentro de él me gustaría acceder a la propiedad del padre ''
userStatus
'', aquí está el hijo:
Component({
selector: ''profile'',
template: require(''app/components/profile/profile.html''),
providers: [],
directives: [],
pipes: []
})
export class Profile implements OnInit {
constructor() {
}
ngOnInit() {
// I want to have access with the parent App Component, ''userStatus'' propety here... I only want to read this property
}
}
Ahora, en Angular 1.x, esto sería fácil, ya que podría hacer referencia a
$parent
en mi controlador secundario o (
¡¡¡ALERTA ANTI PATRÓN!
) Podría ser tan tonto poner estos datos en mi
$rootScope
.
¿Cuál sería la mejor manera de acceder al padre en Angular 2?
En Angular 6, accedo a las propiedades principales inyectando el principal a través del constructor. No es la mejor solución pero funciona:
constructor(@Optional() public parentComponentInjectionObject: ParentComponent){
// And access like this:
parentComponentInjectionObject.thePropertyYouWantToAccess;
}
Hay diferentes maneras:
-
servicio global
-
servicio compartido por el padre e inyectado al niño
-
similar al
servicio global
pero listado en
providers
oviewProviders
en el padre en lugar deboostrap(...)
y solo disponible para hijos del padre.
-
similar al
servicio global
pero listado en
-
padre inyectado al niño y accedido directamente por el niño
- desventaja: acoplamiento apretado
export class Profile implements OnInit {
constructor(@Host() parent: App) {
parent.userStatus ...
}
- el enlace de datos
export class Profile implements OnInit {
@Input() userStatus:UserStatus;
...
}
<profile [userStatus]="userStatus">
Hice un componente genérico donde necesito una referencia al padre que lo usa. Esto es lo que se me ocurre:
En mi componente hice un @Input:
@Input()
parent: any;
Luego, en el padre que usa este componente:
<app-super-component [parent]="this"> </app-super-component>
En el súper componente, puedo usar cualquier cosa que compila del padre:
Atributos:
parent.anyAttribute
Funciones:
parent[myFunction](anyParameter)
Tú podrías:
-
Defina un parámetro
userStatus
para el componente secundario y proporcione el valor cuando utilice este componente desde el elemento primario:@Component({ (...) }) export class Profile implements OnInit { @Input() userStatus:UserStatus; (...) }
y en el padre:
<profile [userStatus]="userStatus"></profile>
-
Inyecte el padre en el componente hijo:
@Component({ (...) }) export class Profile implements OnInit { constructor(app:App) { this.userStatus = app.userStatus; } (...) }
Tenga cuidado con las dependencias cíclicas entre ellos.
Tuve el mismo problema pero lo resolví de manera diferente. No sé si es una buena forma de hacerlo, pero funciona muy bien para lo que necesito.
Usé @Inject en el constructor del componente hijo, así:
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;
}
}
Esto funcionó para mí, solo necesita declarar el método o propiedad que desea llamar como público.
En mi caso, AppComponent maneja el enrutamiento, y estoy usando insignias en los elementos del menú para alertar al usuario de que hay nuevos mensajes no leídos disponibles. Por eso, cada vez que un usuario lee un mensaje, quiero que ese contador se actualice, así que llamo al método de actualización para que el número en el menú de navegación se actualice con el nuevo valor. Probablemente esta no sea la mejor manera, pero me gusta por su simplicidad.