angularjs - Send input til nestet komponent i Angular 2


Hvordan kan attributtene gjennomsiktig oversettes fra wrapper-komponenten til den nestede komponenten?

Med tanke på at det finnes

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 { ... }

Kan inngangene oversettes i batch, slik at de ikke blir oppført i malen?

Koden ovenfor skal gjenskape oppskriften for Angular 1.x-direktiver:

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);
        }
      }
    },
    ...
  };
});

Svar #1

Jeg er ikke sikker på om jeg fikk det riktig, men her er min implementering (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!)'
  }
}

Håper det hjelper :)

Svar #2

Jeg tror dette kan kokes ned til et mer grunnleggende problem uten Angular2 i det hele tatt. Når du har en funksjon som tar mange parametere, er det irriterende og feilutsatt å måtte spesifisere alle disse parameterne hver gang du vil bruke den. Problemet blir verre når det finnes en mellomliggende funksjon som ikke bryr seg om disse parameterne i det hele tatt - du ender opp med å legge til parametere i den mellomliggende funksjonen bare for at den skal kunne sende dem videre til den indre funksjonen. Åh!

Det finnes noen få mønstre for å håndtere dette. Min favoritt er å fullstendig instansiere den indre funksjonen og sende instansen som allerede er lastet med de tidligere pass-through-parameterne innebygd i den. Jeg synes http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/ er et fint innlegg om hvordan man gjør det i Angular 2 ved bruk av @ViewChild og @ContentChild. En annen strategi er å pakke alle pass-through-parameterne inn i ett enkelt objekt, slik at det i det minste bare er en parameter å sende gjennom. Det hjelper også når du vil legge til flere parametere - siden de allerede er pakket inn og sendt gjennom på en lukket måte, trenger ikke pass-through-koden din å endres.

Relaterte artikler