javascript - change - viewchild angular 6
Pasar entradas al componente anidado en Angular 2 (3)
¿Cómo se pueden traducir los atributos de manera transparente del componente contenedor al componente anidado?
Considerando que hay
const FIRST_PARTY_OWN_INPUTS = [...];
const FIRST_PARTY_PASSTHROUGH_INPUTS = [''all'', ''attrs'', ''are'', ''passed''];
@Component({
selector: ''first-party'',
inputs: [...FIRST_PARTY_OWN_INPUTS, ...FIRST_PARTY_PASSTHROUGH_INPUTS],
template: `
<div>
<third-party [all]="all" [attrs]="attrs" [are]="are" [passed]="passed"></third-party>
<first-party-extra></first-party-extra>
</div>
`,
directives: [ThirdParty]
})
export class FirstParty { ... }
¿Pueden las entradas traducirse por lotes para que no se enumeren en la plantilla?
Se supone que el código anterior recrea la receta para las directivas 1.x angulares:
app.directive(''firstParty'', function (thirdPartyDirective) {
const OWN_ATTRS = [...];
const PASSTHROUGH_ATTRS = Object.keys(thirdPartyDirective[0].scope);
return {
scope: ...,
template: `
<div>
<third-party></third-party>
<first-party-extra></first-party-extra>
</div>
`,
compile: function (element, attrs) {
const nestedElement = element.find(''third-party'');
for (let [normalizedAttr, attr] of Object.entries(attrs.$attr)) {
if (PASSTHROUGH_ATTRS.includes(normalizedAttr)) {
nestedElement.attr(attr, normalizedAttr);
}
}
},
...
};
});
Creo que esto se puede reducir a un problema más básico sin Angular2 en absoluto. Cuando tiene una función que toma muchos parámetros, es molesto y propenso a errores tener que especificar todos esos parámetros cada vez que quiera usarlo. El problema empeora cuando hay una función intermedia que no se preocupa por esos parámetros en absoluto: se encuentra agregando parámetros a la función intermedia solo para poder pasarla a la función interna. ¡Yeargh!
Hay algunos patrones para lidiar con esto. Mi favorito es crear una instancia completa de la función interna y pasar la instancia ya cargada con los parámetros de paso anteriores incrustados en ella. Creo que http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/ es una buena publicación sobre cómo hacer eso en Angular 2 usando @ViewChild
y @ContentChild
. Otra estrategia es envolver todos los parámetros de paso en un único objeto, por lo que al menos solo hay que pasar un parámetro. Eso también ayuda cuando desea agregar más parámetros, ya que ya están envueltos y pasados de forma opaca, su código de paso no necesita cambiar.
No estoy seguro de si lo hice bien, pero aquí está mi implementación ( PLUNKER )
const FIRST_PARTY_OWN_INPUTS = [''not'', ''passthrough''];
const FIRST_PARTY_PASSTHROUGH_INPUTS = [''all'', ''attrs'', ''are'', ''passed''];
const generateAttributes(arr) {
return arr.map(att => ''['' + att + ''] = "'' + att + ''"'').join('' '');
}
//-------------------------------------------------------//////////////////
import {Component} from ''@angular/core''
@Component({
selector: ''third-party'',
inputs: [...FIRST_PARTY_PASSTHROUGH_INPUTS],
template: `
<div>
{{all}} , {{attrs}} , {{are}} , {{passed}}
</div>
`
})
export class ThirdParty {
}
@Component({
selector: ''first-party'',
inputs: [...FIRST_PARTY_OWN_INPUTS, ...FIRST_PARTY_PASSTHROUGH_INPUTS],
template: `
<div>
<div>
{{not}} , {{passthrough}}
</div>
<third-party ${generateAttributes(FIRST_PARTY_PASSTHROUGH_INPUTS)}></third-party>
<first-party-extra></first-party-extra>
</div>
`,
directives: [ThirdParty]
})
export class FirstParty {
}
@Component({
selector: ''my-app'',
providers: [],
template: `
<div>
<h2>Hello {{name}}</h2>
<first-party [not]="''not''" [passthrough]="''passthrough''"
[all]="''all''" [attrs]="''attrs''" [are]="''are''" [passed]="''passed''">
</first-party>
</div>
`,
directives: [FirstParty]
})
export class App {
constructor() {
this.name = ''Angular2 (Release Candidate!)''
}
}
Espero que ayude :)
Puede lograr esto utilizando @Input () en sus componentes secundarios.
http://plnkr.co/edit/9iyEsnyEPZ4hBmf2E0ri?p=preview
Componente principal:
import {Component} from ''@angular/core'';
import {ChildComponent} from ''./child.component'';
@Component({
selector: ''my-parent'',
directives: [ChildComponent],
template: `
<div>
<h2>I am the parent.</h2>
My name is {{firstName}} {{lastName}}.
<my-child firstName="{{firstName}}"
lastName="{{lastName}}">
</my-child>
</div>
`
})
export class ParentComponent {
public firstName:string;
public lastName: string;
constructor() {
this.firstName = ''Bob'';
this.lastName = ''Smith'';
}
}
Componente hijo:
import {Component, Input} from ''@angular/core'';
@Component({
selector: ''my-child'',
template: `
<div>
<h3>I am the child.</h3>
My name is {{firstName}} {{lastName}} Jr.
<br/>
The name I got from my parent was: {{firstName}} {{lastName}}
</div>
`
})
export class ChildComponent {
@Input() firstName: string;
@Input() lastName: string;
}
Componente de la aplicación:
//our root app component
import {Component} from ''@angular/core'';
import {ParentComponent} from ''./parent.component'';
@Component({
selector: ''my-app'',
directives: [ParentComponent],
template: `
<div>
<my-parent></my-parent>
</div>
`
})
export class App {
constructor() {
}
}