将输入传递给Angular 2中的嵌套组件

时间:2016-06-30 11:43:40

标签: angularjs angular typescript

如何将属性从包装器组件透明地转换为嵌套组件?

考虑到

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

输入是否可以批量翻译,因此不会在模板中枚举它们?

上面的代码应该重新创建Angular 1.x指令的配方:

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

3 个答案:

答案 0 :(得分:5)

我不确定我是否做得对,但这是我的实施(PLUNKER

Update BLOG
SET Tags = REPLACE(Tags, N',', N'،')

希望它有助于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!)' } }

答案 1 :(得分:0)

您可以在子组件上使用@Input()来完成此操作。

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

父组件:

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

子组件:

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

应用组件:

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

答案 2 :(得分:0)

我认为这可以归结为一个没有Angular2的更基本的问题。当你有一个需要大量参数的函数时,每次你想要使用它时都必须指定所有这些参数,这很烦人且容易出错。当有一个根本不关心那些参数的中间函数时,问题会变得更糟 - 你发现自己将参数添加到中间函数,只是因为它可以将它传递给内部函数。 Yeargh!

有一些模式可以解决这个问题。我最喜欢的是完全实例化内部函数并传递已经加载的实例,其中嵌入了前面的传递参数。我认为http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/是关于如何使用@ViewChild@ContentChild在Angular 2中执行此操作的好文章。另一种策略是将所有传递参数包装在一个对象中,因此至少只有一个参数可以传递。当你想要添加更多参数时,这也很有帮助 - 因为它们已经被包装并且不透明地传递,你的传递代码不需要改变。