只读属性和 ngOnInit
readonly properties and ngOnInit
只读属性只能在构造函数中赋值,但在angular中不鼓励甚至有时不可能使用构造函数进行某些初始化,而是使用angular hook ngOnInit。
有什么方法可以将 ngOnInit 标记为关于 readonly 属性的构造函数,以便我可以将 readonly 用于仅在 ngOnInit 中分配一次的本质上不可变的属性?
编辑:澄清一下:我不是在寻找其他方法来声明只读属性。我想以常规方式声明它们。我认为任何其他不值得为了获得静态检查而牺牲可读性的东西。
我希望会有一些注释,比如 tslint 忽略 ngOnInit 中的不变性。
从目前的答案来看,我想将它们分配为 (this as any).foo = bar;
是最接近我想要做的,但我想它仍然比只留下只读更难看。
您不能将方法标记为构造函数,因为没有相应的语法。您可以通过对 any
使用类型断言来破坏 readonly
这只是编译时检查,并以类型不安全的方式访问您想要的任何 public/private 属性 。您还可以使用映射类型使类型可变,但它仅适用于 public 属性:
type Mutable<T> = { -readonly [ P in keyof T]: T[P] }
class Foo {
public readonly data: string;
private readonly pdata: string;
public init() {
const ref: Mutable<this> = this;
ref.data = ""
const pRef = this as any;
pRef.pdata = ""
const pSaferRef: { pdata: string } = this as any;
pSaferRef.pdata = ""
}
}
为什么不用 setter 和 getter 代替 readonly
?
export class MyComponent {
private _value: string;
set value(v: string) {
if (!this._value) {
this._value = v;
} else {
throw new TypeError('Assignment to read-only variable');
}
}
get value() {
return this._value;
}
}
这是个好问题。 您可以通过 setter:
获得类似的结果
...
protected _pseudoReadonlyProp: number = -1 // or some other value, that marks unititialized state
set pseudoReadonlyProp(a: number) {
if(this._pseudoReadonlyProp != -1) {
// throw some error here
}
this._pseudoReadonlyProp = a
}
get pseudoReadonlyProp(): number {
return this._pseudoReadonlyProp
}
...
获得类似行为的另一种方法是将只读成员封装在 class 中,将其放入您的组件中并在 ngInit 或其他一些中创建 class 的新实例组件初始化函数。
考虑到 Object.defineProperty 存在,更好的方法是按照@trichetriche
指出的那样使用它
Readonly properties can only be assigned in the constructor
不正确
class MyClass {
readonly prop1 = 'prop1';
constructor(
public readonly prop2 = 'prop2'
) {
}
ngOnInit() {
Object.defineProperty(this, 'prop3', { wirtable: false, value: 'prop3'});
}
}
如您所见,已经有 3 种定义方式。可能更多!
but in angular it is discouraged and sometimes impossible to use the constructor for certain initialization and instead the angular hook ngOnInit is used
对于新手来说是"discouraged",因为告诉他们不要那样做比深入解释框架的生命周期更容易。关键是,您可以随意使用构造函数,尤其是对于与 Angular 无关的内容(如只读变量)。
Is there any way to mark ngOnInit as a constructor
构造器就是构造器。您不能将方法定义为构造函数。您只能在构造函数中调用一个方法,但这不能解决您的问题。
so that I can use readonly for essentially immutable properties that are only assigned a single time in ngOnInit?
答案和底线:随意使用构造函数。如果需要,将只读属性放入其中。
此外,请考虑提供一些沙箱或至少一些代码,以便我们可以做出既适合您的代码又适合您的需要的答案。
只读属性只能在构造函数中赋值,但在angular中不鼓励甚至有时不可能使用构造函数进行某些初始化,而是使用angular hook ngOnInit。 有什么方法可以将 ngOnInit 标记为关于 readonly 属性的构造函数,以便我可以将 readonly 用于仅在 ngOnInit 中分配一次的本质上不可变的属性?
编辑:澄清一下:我不是在寻找其他方法来声明只读属性。我想以常规方式声明它们。我认为任何其他不值得为了获得静态检查而牺牲可读性的东西。 我希望会有一些注释,比如 tslint 忽略 ngOnInit 中的不变性。
从目前的答案来看,我想将它们分配为 (this as any).foo = bar;
是最接近我想要做的,但我想它仍然比只留下只读更难看。
您不能将方法标记为构造函数,因为没有相应的语法。您可以通过对 any
使用类型断言来破坏 readonly
这只是编译时检查,并以类型不安全的方式访问您想要的任何 public/private 属性 。您还可以使用映射类型使类型可变,但它仅适用于 public 属性:
type Mutable<T> = { -readonly [ P in keyof T]: T[P] }
class Foo {
public readonly data: string;
private readonly pdata: string;
public init() {
const ref: Mutable<this> = this;
ref.data = ""
const pRef = this as any;
pRef.pdata = ""
const pSaferRef: { pdata: string } = this as any;
pSaferRef.pdata = ""
}
}
为什么不用 setter 和 getter 代替 readonly
?
export class MyComponent {
private _value: string;
set value(v: string) {
if (!this._value) {
this._value = v;
} else {
throw new TypeError('Assignment to read-only variable');
}
}
get value() {
return this._value;
}
}
这是个好问题。 您可以通过 setter:
...
protected _pseudoReadonlyProp: number = -1 // or some other value, that marks unititialized state
set pseudoReadonlyProp(a: number) {
if(this._pseudoReadonlyProp != -1) {
// throw some error here
}
this._pseudoReadonlyProp = a
}
get pseudoReadonlyProp(): number {
return this._pseudoReadonlyProp
}
...
获得类似行为的另一种方法是将只读成员封装在 class 中,将其放入您的组件中并在 ngInit 或其他一些中创建 class 的新实例组件初始化函数。
考虑到 Object.defineProperty 存在,更好的方法是按照@trichetriche
指出的那样使用它Readonly properties can only be assigned in the constructor
不正确
class MyClass {
readonly prop1 = 'prop1';
constructor(
public readonly prop2 = 'prop2'
) {
}
ngOnInit() {
Object.defineProperty(this, 'prop3', { wirtable: false, value: 'prop3'});
}
}
如您所见,已经有 3 种定义方式。可能更多!
but in angular it is discouraged and sometimes impossible to use the constructor for certain initialization and instead the angular hook ngOnInit is used
对于新手来说是"discouraged",因为告诉他们不要那样做比深入解释框架的生命周期更容易。关键是,您可以随意使用构造函数,尤其是对于与 Angular 无关的内容(如只读变量)。
Is there any way to mark ngOnInit as a constructor
构造器就是构造器。您不能将方法定义为构造函数。您只能在构造函数中调用一个方法,但这不能解决您的问题。
so that I can use readonly for essentially immutable properties that are only assigned a single time in ngOnInit?
答案和底线:随意使用构造函数。如果需要,将只读属性放入其中。
此外,请考虑提供一些沙箱或至少一些代码,以便我们可以做出既适合您的代码又适合您的需要的答案。