我目前正在使用Angular2(Dart)创建一个可重复使用的搜索框组件,其中包含一个建议框。
我遇到的麻烦是我不确定如何通过支持更丰富的建议类型来使建议框可扩展,例如带图标的建议,多行文本的建议,文本的不同样式,动画等等。
目前,建议框HTML(已拆除)看起来有点像这样:
<div class="suggestion-box-container">
<div class="suggestion" *ng-for="#suggestion of model.suggestions">
{{ suggestion.text }}
</div>
</div>
Dart代码看起来像这样:
@Component(
selector: 'suggestion-box'
)
@View(
templateUrl: 'suggestion_box.html',
directives: const [NgFor]
)
class SuggestionBox {
final SuggestionModel model;
// ...
}
class SuggestionModel {
List<Suggestion> suggestions = [];
// ...
}
class Suggestion {
String text;
// ...
}
我想知道如何修改此设计,以便用户可以扩展Suggestion
并编写自己的相应建议组件。
我考虑过像
<basic-suggestion *ng-if="suggestion.type == 'basic'"></basic-suggestion>
<icon-suggestion *ng-if="suggestion.type == 'icon'"></icon-suggestion>
...
但当然,随着支持更多建议类型,这将会失控,并且还需要将(^hover)
和(^click)
处理程序复制到每种类型的建议中。更糟糕的是,它需要修改原始库而不是仅以模块化方式使用它。
这种事情有优雅的解决方案吗?或者,如果用户想要更丰富的建议,他们是否会更好地完全写出自己的建议箱?我希望避免这种情况,因为我想在搜索框/建议框中加入一堆辅助功能,用户不需要重写。
编辑:根据Gunter的回答,我已经设法改进了一点:
<suggestion-box>
<div *ng-for="#suggestion in suggestions">
<suggestion suggestion-instance="suggestion">
<!-- Custom suggestion code goes here.
The following is an example -->
<img src="{{suggestion.iconSrc}}"></img> {{suggestion.text}}
</suggestion>
</div>
</suggestion>
我有一个新的suggestion
组件,看起来有点像这样:
@Component(
selector: 'suggestion',
properties: const ['suggestion: suggestion-instance']
)
@View(
template: '''
<div (^click)="handleClick(suggestion)"
(hover)="handleHover(suggestion)">
<content></content>
</div>
'''
)
class SuggestionComponent {
final SuggestionModel model;
final Suggestion suggestion;
// ...
}
现在这有点好了,因为用户现在可以开箱即用了辅助功能/键盘控制/鼠标控制。但这仍然不理想。我不知何故喜欢模板根据suggestion
的实际子类自动确定要使用的适当组件。我想我可以在每个组件中定义一个方法,如getTemplate()
,但这可能不是一种非常角色的方式。
答案 0 :(得分:1)
我还没有真正使用过Angular2,但我认为至少有两种方法可以做到
- 您应该能够扩展组件(只需创建派生类并专门化行为
- 使用具有shadow DOM的<content>
标记的合成。我在这里找到了一些文档https://www.airpair.com/angularjs/posts/creating-components-p3-angular2-directives
- 或两者的组合
<强>更新强>
版本3.2将支持扩展组件。
类似于@HostBinding()
,@HostListener()
,@ViewChild()
,@ContentChild()
的注释将在子类上被识别,因此将是OnInit
和其他lifecycle回调的接口< / p>
除了inheritanc之外,还有不同的方法可以自定义组件
您可以使用DynamicComponentLoader,通过搜索框传递要实例化的组件类型
传递子项以显示在<ng-content>
个位置,
或者传递<template>
内容,由您的搜索组件动态添加,也可能是其他内容。