angularjs - ارسال ورودیها به کامپوننت تو در تو در Angular 2


چگونه میتوان ویژگیها را بهصورت شفاف از کامپوننت Wrapper به کامپوننت تو در تو منتقل کرد؟

با توجه به این که وجود دارد

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

پاسخ شماره ۱

مطمئن نیستم که درست متوجه شدهام یا نه، اما این پیادهسازی من است ( 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!)'
  }
}

امیدوارم مفید باشد :)

پاسخ شماره ۲

من فکر میکنم میتوان این مسئله را به یک مشکل اساسیتر بدون هیچ ارتباطی با Angular2 تقلیل داد. وقتی شما تابعی دارید که پارامترهای زیادی میگیرد، مجبور شدن به مشخص کردن تمام آن پارامترها هر بار که میخواهید از آن استفاده کنید، آزاردهنده و مستعد خطا است. مشکل وقتی بدتر میشود که یک تابع میانی وجود داشته باشد که اصلاً به آن پارامترها اهمیت نمیدهد - خودتان را پیدا میکنید که پارامترها را به تابع میانی اضافه میکنید فقط تا بتواند آن را به تابع داخلی منتقل کند. ای وای!

چند الگو برای مقابله با این وجود دارد. مورد علاقه من این است که تابع داخلی را به طور کامل نمونهسازی کرده و نمونه را که قبلاً با پارامترهای گذرا قبلی پر شده است، عبور دهیم. فکر میکنم http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/ یک پست خوب درباره نحوه انجام این کار در Angular 2 با استفاده از @ViewChild و @ContentChild است. استراتژی دیگر این است که همه پارامترهای گذرا را در یک شیء واحد بستهبندی کنید، بنابراین حداقل تنها یک پارامتر برای عبور دادن وجود دارد. این همچنین وقتی که میخواهید پارامترهای بیشتری اضافه کنید مفید است - از آنجایی که آنها قبلاً بستهبندی شده و به صورت غیرشفاف عبور داده میشوند، کد عبوری شما نیازی به تغییر ندارد.