31 votes

Pass entrées imbriquées composante Angulaire 2

Comment les attributs de manière transparente traduit de composant wrapper imbriquées composant?

Considérant qu'il y a

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

Peut les entrées soient traduits en batch, afin de ne pas être énumérés dans le modèle?

Le code ci-dessus est censé recréer la recette Angulaire 1.x les 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);
        }
      }
    },
    ...
  };
});

6voto

Ankit Singh Points 15545

Je ne suis pas sûr si j'ai bien compris, mais voici mes mise en œuvre ( 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!)'
  }
}

Espérons qu'il aidera :)

0voto

Riley Lark Points 11212

Je pense que cela peut se résument à un problème sans Angular2 à tous. Lorsque vous avez une fonction qui prend un nombre important de paramètres, c'est ennuyeux et sujette à erreur d'avoir à spécifier tous les paramètres à chaque fois que vous souhaitez l'utiliser. Le problème s'aggrave quand il y a un intermédiaire de la fonction qui ne se soucie pas de ces paramètres à tous - vous trouver vous-même en ajoutant des paramètres à l'intermédiaire de la fonction juste de sorte qu'il peut passer à l'intérieur de la fonction. Yeargh!

Il y a quelques modèles pour traiter cette question. Mon préféré est entièrement instancier la fonction interne et de transmettre l'instance déjà chargé avec l'ex-passer-par l'intermédiaire des paramètres qui y est incorporé. Je pense http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/ est un joli post sur comment faire cela dans Angulaire à l'aide de 2 @ViewChild et @ContentChild. Une autre stratégie consiste à envelopper tous les paramètres en un seul objet, donc au moins il n'y a qu'un seul paramètre à passer à travers. Cela aide aussi quand vous voulez ajouter d'autres paramètres, car ils sont déjà enveloppé et traversé de manière opaque, votre pass-through code n'a pas besoin de changer.

-1voto

Nick Acosta Points 1541

Vous pouvez accomplir cela en utilisant @Input() sur votre enfant composants.

http://plnkr.co/edit/9iyEsnyEPZ4hBmf2E0ri?p=preview

Composant Parent:

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';
  }
}

Composant Enfant:

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;
}

App De La Composante:

//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() {
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X