typescript - 具有默认属性值的 Typescript mixins(从新的 MyClass 派生)
问题描述
我正在使用 Typescript 中的一些 mixin 进行试验,并且已经掌握了使用几种不同方法构建 mixin 的基础知识。在所有这些中,我都遇到了同样的错误。
这是我的混合类:
export class OnDestroyMixin implements OnDestroy {
public destroyStream: Subject<void> = new Subject();
ngOnDestroy(): void {
console.log(`on destroy from mixin`);
this.destroyStream.next();
this.destroyStream.complete();
}
}
并且每当调用 on destroy 函数(在将其混合到另一个类之后)时,this.destroyStream
它都不存在,所以我得到一个Cannot read property 'next' of undefined
错误。
我考虑过在构造函数中设置它,但我不确定构造函数在 mixins 中是如何工作的......
我认为这应该是可能的。
我目前使用的 mixin 方法是一个 mixin 装饰器:
export function Mixin(baseCtors: Function[]) {
return function (derivedCtor: Function) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
const descriptor = Object.getOwnPropertyDescriptor(baseCtor.prototype, name);
if (name === 'constructor')
return;
if (descriptor && (!descriptor.writable || !descriptor.configurable || !descriptor.enumerable || descriptor.get || descriptor.set)) {
Object.defineProperty(derivedCtor.prototype, name, descriptor);
} else {
derivedCtor.prototype[name] = baseCtor.prototype[name];
}
});
});
};
}
我从网上某处复制了它,但正如我所说,我尝试了几种不同的方法,它们基本上都将属性从一个原型复制到另一个原型。
解决方案
这个问题的根本原因是当你在一个类上定义一个属性值时,当它被转换为 JavaScript 时,这个值是在构造函数中设置的。上面的 mixin 代码专门忽略了构造函数。这里真正的解决方案是将 2 个类构造函数合并在一起。
Typescript 中似乎有两种不同的 mixins 方法。类似于我的问题中的一种方法,我们遍历原型属性并将它们从一个类复制到另一个类,而在另一个类中,我们只需返回一个扩展原始类的新类:
function Flies<TBase extends Constructor>(Base: TBase) {
return class extends Base {
fly() {
alert('Is it a bird? Is it a plane?');
}
};
}
我原以为我无法在 Angular 中使用它,因为它是一个返回新类的函数,但它完全有可能如此处所示:
class SourceClass{}
@Component({
selector: 'some-selector',
templateUrl: './some-selector.html',
styleUrls: ['./some-selector.scss']
})
export class SampleMixedClass extends Flies(SourceClass) {}
推荐阅读
- php - 如何编写此 MySQL 子查询以选择具有共同值和一个已知值的行
- android - 为什么在 Jetpack Compose 的下一页中显示 BottomNavigation?
- python - 在 tensorflow 中的 tf.function 函数中使用循环、tf.Variable、tf.tensorarray
- spring-boot - MyBatis - SpringBoot 将结果映射到错误的对象
- linux - FreeBSD 动态库可以在 Orbis(ps4 或 ps5 系统)上运行吗?
- mysql - 不在 localhost 端口上运行 Express Node.js?
- javascript - 我的 React-Bootstrap Button 和 Dropdown 大小不同
- android - 远程打开设备上的应用程序
- reactjs - 当用户修改数据时,mutate 会导致 react-table 错误:不是函数
- ruby-on-rails - Ruby on Rails 变量在视图中显示 Active Record 数据而不是整数