gpt4 book ai didi

typescript - 如何在不重复写入某些组件的情况下导入指令

转载 作者:搜寻专家 更新时间:2023-10-30 22:02:18 24 4
gpt4 key购买 nike

我正在使用 Angular2 和 TypeScript 创建 Web 应用程序。当我创建一些 CustomElements(这意味着组件和指令、验证器)时,我发现我为每个组件编写了 directives: [...] 代码,以便像下面的代码一样导入 CustomElements。

// my_comopnent_1.comopnent.ts
@Component({
selector: 'my-component-1',
directives: [
ROUTER_DIRECTIVES,
MyDirective1,
MyDirective2,
MyValidator1,
MyValidator2,
...
],
})

// my_comopnent_2.comopnent.ts
@Component({
selector: 'my-component-2',
directives: [
ROUTER_DIRECTIVES,
MyDirective1,
MyDirective2,
MyValidator1,
MyValidator2,
...
],
})

// my_comopnent_3.comopnent.ts
@Component({
selector: 'my-component-3',
directives: [
ROUTER_DIRECTIVES,
MyDirective1,
MyDirective2,
MyValidator1,
MyValidator2,
...
],
})

是否存在无需重复编写 directives: [...] 即可导入某些 CustomComponents 的方式,例如事件冒泡或原型(prototype)链?我的理想是,当我将代码写入父组件时,其子组件包含父组件导入的 CustomElements。

// parent.component.ts
@Component({
selector: 'parent',
directives: [MyDirective1, ...],
})

// child.component.ts
@Component({
selector: 'child',
template: `
// It's possible to use MyDirective because of importing by ParentComponent.
<div my-directive></div>
`,
})

最佳答案

您可以通过这种方式将它们定义为平台指令:

export const GENERAL_DIRECTIVES: any[] = [
ROUTER_DIRECTIVES,
MyDirective1,
MyDirective2,
MyValidator1,
MyValidator2,
(...)
];

bootstrap(App, [
provide(PLATFORM_DIRECTIVES, {useValue: [GENERAL_DIRECTIVES], multi: true})
]);

这样您就不需要每次都导入它们。

有关详细信息,请参阅此问题:

这种方法的主要缺点是它们对于应用程序中的所有组件都是全局的。另一种方法包括创建一个自定义装饰器,它扩展组件元数据(directives 属性)以添加这些组件/指令。通过这种方式,您可以精细地控制要在何处自动指定这些指令。

这个机制可以依赖于继承,即一个抽象的根组件。

这是一个示例:

export function CustomComponent(annotation: any) {
return function (target: Function) {
var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

var parentAnnotation = parentAnnotations[0];
Object.keys(parentAnnotation).forEach(key => {
if (isPresent(parentAnnotation[key])) {
if (key === 'directives') {
// merge directives attributes
let parentDirectives = parentAnnotation[key] || [];
let currentDirectives = annotation[key] || [];
currentDirectives.concat(parentDirectives);
} else {
annotation[key] = parentAnnotation[key];
}
}
});
var metadata = new ComponentMetadata(annotation);

Reflect.defineMetadata('annotations', [ metadata ], target);
}
}

并使用它:

@Component({
directives: [
ROUTER_DIRECTIVES,
MyDirective1,
MyDirective2,
MyValidator1,
MyValidator2,
(...)
]
})
export class AbstractComponent {
}

@CustomComponent({
selector: 'sub',
template: `
(...)
`
})
export class SubComponent extends AbstractComponent {
}

@Component({
selector: 'app',
template: `
<sub></sub>
`,
directives [ SubComponent ]
})
export class App {
}

有关详细信息,请参阅此问题:

关于typescript - 如何在不重复写入某些组件的情况下导入指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36999041/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com