Учитывая модель раздела страницы, которая содержит несколько полей и будут заполнены данными, такие как это:Динамический компонент в Angular2
{
"fields": [
{
"id": 1,
"type": "text",
"caption": "Name",
"value": "Bob"
},
{
"id": 2,
"type": "bool",
"caption": "Over 24?",
"value": 0
},
{
"id": 3,
"type": "options",
"options" : [ "M", "F"],
"caption": "Gender",
"value": "M"
}
]
}
Я хотел бы иметь общий раздел компонент, который не знает о различные типы полей, которые он мог бы обернуть, чтобы избежать множества условной логики в шаблоне раздела, а также создавать новые виды/компоненты типа поля, добавляемые путем сброса в автономный файл, а не для изменения отдельного компонента.
Мой идеал был бы для селектора компонентов достаточно конкретным, чтобы я мог выполнить это, выбрав элемент в шаблоне родительского компонента на основе значений атрибутов, привязанных к модели. Например: (простите любые проблемы синтаксиса, как я закодированы это в окне SO, основная часть, чтобы обратить внимание на это селектор на BooleanComponent.ts
SectionComponent.ts
@Component({
selector: 'my-app'
})
@View({
template: `
<section>
<div *ng-for="#field of fields">
<field type="{{field.type}}"></field>
</div>
</section>
`,
directives: [NgFor]
})
class SectionComponent {
fields: Array<field>;
constructor() {
this.fields = // retrieve section fields via service
}
}
FieldComponent.ts:
// Generic field component used when more specific ones don't match
@Component({
selector: 'field'
})
@View({
template: `<div>{{caption}}: {{value}}</div>`
})
class FieldComponent {
constructor() {}
}
BooleanComponent.ts:
// specific field component to use for boolean fields
@Component({
selector: 'field[type=bool]'
})
@View({
template: `<input type="checkbox" [id]="id" [checked]="value==1"></input>`
})
class BooleanComponent {
constructor() {}
}
... и со временем я бы добавить новое совместное чтобы обеспечить специальные шаблоны и поведение для других конкретных типов полей или даже полей с определенными заголовками и т. д.
Это не работает, поскольку селектор компонентов должен быть простым именем элемента (в альфах -26 и альфа-27 при наименее). Мое исследование бесед github побудило меня поверить, что это ограничение было расслабленным, но я не могу определить, действительно ли то, что я хочу сделать, на самом деле будет поддерживаться.
В качестве альтернативы, я видел упомянутый DynamicComponentLoader, хотя теперь я не могу найти пример, который, как я думал, был в руководстве angle.ioio.io. Тем не менее, я не знаю, как его можно использовать для динамической загрузки компонента, для которого он не знает имя или критерии соответствия.
Есть ли способ выполнить мою задачу развязывания специализированных компонентов от их родителей, используя либо технику, аналогичную той, которую я пробовал, либо какую-либо другую технику, о которой я не знаю в Angular 2?
UPDATE 2015-07-06
http://plnkr.co/edit/fal9OA7ghQS1sRESutGd?p=preview
Я подумал, что лучше всего, чтобы показать ошибки впадаю в более явном виде. Я включил плунж с некоторым примером кода, но только первая из этих трех ошибок будет видна, так как каждая из них блокирует другую, поэтому вы можете показывать только по одному. Я жестко закодирован, чтобы обойти №2 и №3 на данный момент.
- ли мой селектор на BooleanComponent является
selector: 'field[type=bool]'
илиselector: '[type=bool]'
, я получаю стека ошибок от Angular какКомпонент «BooleanComponent» может иметь только селектор элемента, но имел "[тип = BOOL]
<field [type]="field.type"></field>
не привязывает мое значение field.type к атрибуту type, но дает мне эту ошибку (которая, к счастью, появляется сейчас в alpha 28.В альфа-26 я был раньше, он не прошел молча). Я могу избавиться от этой ошибки, добавив свойство type в свой FieldComponent и производный BooleanComponent и подключив его к коллекции свойств @Component, но мне это не нужно ни для чего в компонентах.не может связываться с «типа», так как это не знать свойство элемента «поля» и нет согласования директив с соответствующим свойством
- Я вынужден перечислить FieldComponent и BooleanComponent в списке директив моей аннотации SectionComponent View, или они не будут найдены и применены. Я прочитал обсуждения в дизайне команды Angular, где они приняли это сознательное решение в пользу объяснения, чтобы уменьшить возникновение столкновений с директивами во внешних библиотеках, но это нарушает всю идею компонентов, которые я пытаюсь достичь.
На данный момент, я изо всех сил пытаюсь понять, почему Angular2 даже беспокоится о селекторах. Родительский компонент уже должен знать, какие дочерние компоненты он будет иметь, куда они пойдут, и какие данные им нужны. Селекторы в настоящее время совершенно лишние, это также может быть соглашение о совпадении классов. Я не вижу абстракции между компонентами, которые мне нужны, чтобы разделить их.
Из-за этих ограничений в способности рамки Angular2 я делаю свою собственную схему регистрации компонентов и размещаю их через DynamicComponentLoader, но мне все же было бы очень любопытно видеть ответы для людей, которые нашли лучшее способ сделать это.
Большой вопрос. Я столкнулся с той же проблемой. Я обнаружил, что в альфа-34 мы получим частичное решение. Любой элемент управления будет разрешен для компонентов. Вы можете проверить это здесь https://github.com/angular/angular/pull/3336. Но, тем не менее, проблема динамического отбора остается актуальной. Я хотел бы увидеть ваше решение с DynamicComponentLoader, если это возможно. –
Хороший вопрос, мы стараемся избегать большого блока swtich или ngIf на странице. – nycynik