How can the attributes be transparently translated from wrapper component to nested component?
Considering that there is
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 { ... }
Can the inputs be translated in batch, so they would not be enumerated in template?
The code above is supposed to recreate the recipe for Angular 1.x directives:
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); } } }, ... }; });
Firstly, we have to create a custom property to pass the data into a component. This can be done via input binding, which passes data from one component to another, generally from parent to child. This custom input binding is created by using the @Input() decorator.
For passing the data from the child component to the parent component, we have to create a callback function in the parent component and then pass the callback function to the child component as a prop. This callback function will retrieve the data from the child component.
I'm not sure if I got it right but here is my implementation ( 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!)' } }
Hope it helps :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With