【发布时间】:2016-11-02 11:47:20
【问题描述】:
如何将属性从包装组件透明地转换为嵌套组件?
考虑到有
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);
}
}
},
...
};
});
【问题讨论】:
-
你设置 wirg setAttribute 的什么值来得到错误?
-
@GünterZöchbauer 我猜这个错误是由 onInit 中的
this.elementRef.nativeElement.querySelector('third-party').setAttribute('[attr]', 'attr')之类的东西引起的。改用bind-attr不会触发错误,但也无济于事。无论如何,我很肯定有一些惯用的方式来以编程方式建立数据绑定,而且看起来这不是其中之一。 -
@olsn 这可能是大量组件/指令的典型任务。并且可以抽象为辅助函数。有时 WET 代码更可取,有时则不是,这是开发人员的选择。我认为,缺乏如何保持干燥的知识并不是 WET 的借口。是的,它们是带有重音符号的模板文字。
-
@GünterZöchbauer 这是通过添加样式/额外标记/任何东西来自定义第三方组件的经典场景。以前做过很多。 “如果你想定制,就包装它”是惯用的,如果我错了,请纠正我。我在this question 中研究了解决该问题的另一种方法,得出的结论并不乐观。
-
我认为目前最好的选择是只转发每个输入并明确地输出。如果您需要大量使用代码生成。
标签: angularjs angular typescript