I'm using a property decorator Field
which pushes its' key to a fields
Reflect metadata property:
export function Field(): PropertyDecorator {
return (target, key) => {
const fields = Reflect.getMetadata('fields', target) || [];
if (!fields.includes(key)) {
fields.push(key)
}
Reflect.defineMetadata('fields', fields, target)
}
}
I then have an abstract base-class Form
that accesses the metadata in a getter accessory:
abstract class Form {
get fields() {
return Reflect.getMetadata('fields', this) || [];
}
}
I have so far been able to use it successfully to distinguish form fields from other class properties. Consider these classes:
abstract class UserForm extends Form {
@Field()
public firstName: string
@Field()
public lastName: string
get fullName() {
return this.firstName + ' ' + this.lastName;
}
}
class AdminForm extends UserForm {
@Field()
roles: string[]
}
const form = new AdminForm()
console.log(form.fields)
// ['roles', 'firstName', 'lastName']
The problem occurs when I define a sister class to AdminForm
- MemberForm
. When multiple subclasses exists to Form
it seems the fields
getter returns all fields:
class MemberForm extends UserForm {
@Field()
memberSince: Date;
}
const form = new AdminForm()
console.log(form.fields)
// ['roles', 'firstName', 'lastName', 'memberSince'] <--!!!
This makes no sense to me. Why does the memberSince
field appear on an instance of AdminForm
? How can I define different fields on different subclasses?
getMetadata
togetOwnMetadata
on the property decorator, then I get['roles']
onfields
. So what do you mean by walking up the property chain? – Hilleary