Angular2 데코레이터를 래핑하는 일부 기능을 만들려고합니다.TypeScript의 데코레이터 내에서 데코레이터를 재사용하는 방법
경고 : 그래서 나는 다음을 만들어 호스트에 CSS 클래스를 추가하는 과정을 단순화 할
type Constructor = {new(...args: any[]): {}};
export function AddCssClassToHost<T extends Constructor>(cssClass: string) {
return function (constructor: T) {
class Decorated extends constructor {
@HostBinding("class") cssClass = cssClass;
}
// Can't return an inline class, so we name it.
return Decorated;
};
}
내가 또 다른를 만들 수 있도록하려면 AOT 컴파일 작동하지 않는다 특정 CSS 클래스를 추가하는 데코레이터.
/**
* Decorator to be used for components that are top level routes. Automatically adds the content-container class that is
* required so that the main content scrollbar plays nice with the header and the header won't scroll away.
*/
export function TopLevelRoutedComponent<T extends Constructor>(constructor: T) {
// This causes an error when called as a decorator
return AddCssClassToHost("content-container");
// Code below works, I'd like to avoid the duplication
// class Decorated extends constructor {
// @HostBinding("class") cssClass = "content-container";
// }
// return Decorated;
}
// Called like
@TopLevelRoutedComponent
@Component({
selector: "vcd-administration-navigation",
template: `
<div class="content-area">
<router-outlet></router-outlet>
</div>
<vcd-side-nav [navMenu]="navItems"></vcd-side-nav>`
})
export class AdminNavigationComponent {
navItems: NavItem[] = [{nameKey: "Multisite", routerLink: "multisite"}];
}
내가 오류 메시지가
TS1238: Unable to resolve signature of class decorator when called as an expression. Type '(constructor: Constructor) => { new (...args: any[]): AddCssClassToHost<Constructor>.Decorated; p...' is not assignable to type 'typeof AdminNavigationComponent'. Type '(constructor: Constructor) => { new (...args: any[]): AddCssClassToHost<Constructor>.Decorated; p...' provides no match for the signature 'new(): AdminNavigationComponent'
내가 모두
function wrapWithHostBindingClass<T extends Constructor>(constructor: T, cssClass: string) {
class Decorated extends constructor {
@HostBinding("class") cssClass = cssClass;
}
return Decorated; // Can't return an inline decorated class, name it.
}
export function AddCssClassToHost(cssClass: string) {
return function(constructor) {
return wrapWithHostBindingClass(constructor, cssClass);
};
}
export function TopLevelRoutedComponent(constructor) {
return wrapWithHostBindingClass(constructor, "content-container");
}
에 의해 호출되는 함수를 작성하여 해결 할 수 있었다입니다 거기 도우미 기능을 필요로하지 않거나 코드를 복제하지 않고 첫 번째 스타일 작업을 수행하는 방법은 무엇입니까? 나는 내 시도가 훌륭하지 않다는 것을 깨닫고 이해하지 못한다. 그러나 나는 오류 메시지 주위에 머리를 맞출 수가 없었다. (가지)이다
버전 AOT 호환 다음이 훨씬 간단하기 때문에, 그것은 AOT 컴파일러 충돌이 발생하지 않습니다. 그러나 webpack 컴파일러를 사용하는 경우 사용자 정의 데코레이터가 제거되므로 ngc로 컴파일 할 때만 작동합니다.
export function TopLevelRoutedComponent(constructor: Function) {
const propertyKey = "cssClass";
const className = "content-container";
const descriptor = {
enumerable: false,
configurable: false,
writable: false,
value: className
};
HostBinding("class")(constructor.prototype, propertyKey, descriptor);
Object.defineProperty(constructor.prototype, propertyKey, descriptor);
}
가 큰 작품이다 리턴 장식하는 형식 매개 변수를 이동, 우리의 원래 장식 공장을 다시 작성하여, 나는하지 않았다 거의 부끄러워 것을 할 수 이걸 생각해 보라 –
조금 미묘하다. 대상을 제자리에서 수정하는 대신 데코레이터가 새로운 클래스를 반환하므로 새 클래스를 원본에 할당 할 수 있어야합니다. 대부분의 데코레이터는 타겟을 변경하고'void '를 반환합니다. –
@JuanMendes는 머리를 위로하고 데코레이터를 추상화하는 본능은 합리적이고 합리적입니다 (DRY를 유지하고 재사용을 촉진하며 앱 수준의 패턴을 코드화하는 데 도움이됩니다). TypeScript 또는 JavaScript로 작성하는 경우에만 작동합니다. 바벨 - 플러그인 - 변형 - 데코레이터 - 유산). Angular의 AOT 언어로 작성하는 경우 데코레이터를 사용할 수 없습니다. –