Учитывая модель для раздела страницы, которая содержит несколько полей и будет заполнена такими данными, как:
{
"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"
}
]
}
Я хотел бы иметь общий раздел "Компонент", который не знает о различных типах полей, которые он мог бы обернуть, чтобы избежать большого количества условной логики в шаблоне раздела и создавать новые виды/компоненты типа поля, добавляемые путем сброса в автономном файле, а не для изменения отдельного компонента.
Мой идеал был бы для селектора компонентов достаточно конкретным, чтобы я мог выполнить это, выбрав элемент в родительском шаблоне Component на основе значений атрибутов, привязанных к модели. Например: (извините за какие-либо проблемы с синтаксисом, поскольку я закодировал это в 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, хотя теперь я не могу найти пример, который, как я думал, был в руководстве angular.io. Тем не менее, я не знаю, как его можно было бы использовать для динамической загрузки компонента, который не знает имени или критериев соответствия.
Есть ли способ выполнить мою задачу развязывания специализированных компонентов от их родителей, используя либо технику, аналогичную той, которую я пробовал, либо какую-либо другую технику, о которой я не знаю в Angular 2?
ОБНОВЛЕНИЕ 2015-07-06
http://plnkr.co/edit/fal9OA7ghQS1sRESutGd?p=preview
Я подумал, что лучше показать ошибки, с которыми я сталкиваюсь более явно. Я включил плунж с некоторым примером кода, но только первая из этих трех ошибок будет видна, так как каждая из них блокирует другую, поэтому вы можете показывать только по одному. Я жестко закодирован, чтобы обойти № 2 и № 3 на данный момент.
- Будет ли мой селектор в BooleanComponent
selector: 'field[type=bool]'
илиselector: '[type=bool]'
, я получаю стек ошибок из Angular какКомпонент "BooleanComponent" может иметь только селектор элементов, но имеет "[type = bool]"
-
<field [type]="field.type"></field>
не привязывает значение моего значения field.type к атрибуту type, но дает мне эту ошибку (что, к счастью, теперь появляется в alpha 28. В alpha 26 я был ранее включен, он не прошел молча). Я могу избавиться от этой ошибки, добавив свойство type в свой FieldComponent и производный BooleanComponent и подключив его к коллекции свойств @Component, но мне это не нужно ни для чего в компонентах.Нельзя привязываться к "типу", так как это не свойство know элемента "field", и нет соответствующих директив с соответствующим свойством
- Я вынужден перечислить FieldComponent и BooleanComponent в списке директив моей аннотации SectionComponent View, иначе они не будут найдены и применены. Я прочитал обсуждения в дизайне от команды Angular, где они приняли это сознательное решение в пользу объяснения, чтобы уменьшить случаи столкновений с директивами во внешних библиотеках, но это нарушает всю идею о компонентах drop-in, которые я пытаюсь достичь.
В этот момент я изо всех сил пытаюсь понять, почему Angular2 даже беспокоит наличие селекторов. Родительский компонент уже должен знать, какие дочерние компоненты он будет иметь, куда они пойдут, и какие данные им нужны. Селекторы в настоящее время совершенно лишние, это также может быть соглашение о совпадении классов. Я не вижу абстракции между компонентами, которые мне нужны, чтобы отделить их.
Из-за этих ограничений в способности структуры Angular2 я делаю свою собственную схему регистрации компонентов и размещаю их через DynamicComponentLoader, но мне все же было бы очень интересно увидеть ответы для людей, которые нашли лучший способ добиться этого.