Vai al contenuto principale

Listener e Sottoscrittori di Entità

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Cos'è un Listener di Entità?

Qualsiasi tua entità può contenere metodi con logica personalizzata che ascoltano eventi specifici dell'entità. Devi contrassegnare tali metodi con decoratori speciali in base all'evento che desideri monitorare.

Nota: Non effettuare chiamate al database all'interno di un listener, opta invece per sottoscrittori.

@AfterLoad

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @AfterLoad e TypeORM lo richiamerà ogni volta che l'entità viene caricata tramite QueryBuilder o metodi find di repository/manager. Esempio:

@Entity()
export class Post {
@AfterLoad()
updateCounters() {
if (this.likesCount === undefined) this.likesCount = 0
}
}

@BeforeInsert

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @BeforeInsert e TypeORM lo richiamerà prima che l'entità venga inserita tramite il metodo save di repository/manager. Esempio:

@Entity()
export class Post {
@BeforeInsert()
updateDates() {
this.createdDate = new Date()
}
}

@AfterInsert

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @AfterInsert e TypeORM lo richiamerà dopo che l'entità è stata inserita tramite il metodo save di repository/manager. Esempio:

@Entity()
export class Post {
@AfterInsert()
resetCounters() {
this.counters = 0
}
}

@BeforeUpdate

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @BeforeUpdate e TypeORM lo richiamerà prima che un'entità esistente venga aggiornata tramite il metodo save di repository/manager. Tieni presente che ciò avviene solo quando vengono modificate informazioni nel modello. Se esegui save senza modificare nulla nel modello, @BeforeUpdate e @AfterUpdate non verranno eseguiti. Esempio:

@Entity()
export class Post {
@BeforeUpdate()
updateDates() {
this.updatedDate = new Date()
}
}

@AfterUpdate

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @AfterUpdate e TypeORM lo richiamerà dopo che un'entità esistente è stata aggiornata tramite il metodo save di repository/manager. Esempio:

@Entity()
export class Post {
@AfterUpdate()
updateCounters() {
this.counter = 0
}
}

@BeforeRemove

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @BeforeRemove e TypeORM lo richiamerà prima che un'entità venga rimossa tramite il metodo remove di repository/manager. Esempio:

@Entity()
export class Post {
@BeforeRemove()
updateStatus() {
this.status = "removed"
}
}

@AfterRemove

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @AfterRemove e TypeORM lo richiamerà dopo che l'entità è stata rimossa tramite il metodo remove di repository/manager. Esempio:

@Entity()
export class Post {
@AfterRemove()
updateStatus() {
this.status = "removed"
}
}

@BeforeSoftRemove

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @BeforeSoftRemove e TypeORM lo richiamerà prima che un'entità venga rimossa temporaneamente (soft remove) tramite il metodo softRemove di repository/manager. Esempio:

@Entity()
export class Post {
@BeforeSoftRemove()
updateStatus() {
this.status = "soft-removed"
}
}

@AfterSoftRemove

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @AfterSoftRemove e TypeORM lo richiamerà dopo che l'entità è stata rimossa temporaneamente (soft remove) tramite il metodo softRemove di repository/manager. Esempio:

@Entity()
export class Post {
@AfterSoftRemove()
updateStatus() {
this.status = "soft-removed"
}
}

@BeforeRecover

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @BeforeRecover e TypeORM lo richiamerà prima che un'entità venga ripristinata tramite il metodo recover di repository/manager. Esempio:

@Entity()
export class Post {
@BeforeRecover()
updateStatus() {
this.status = "recovered"
}
}

@AfterRecover

Puoi definire un metodo con nome arbitrario nell'entità e contrassegnarlo con @AfterRecover e TypeORM lo richiamerà dopo che l'entità è stata ripristinata tramite il metodo recover di repository/manager. Esempio:

@Entity()
export class Post {
@AfterRecover()
updateStatus() {
this.status = "recovered"
}
}

Cos'è un Sottoscrittore?

Contrassegna una classe come sottoscrittore di eventi in grado di monitorare eventi specifici di un'entità o eventi di qualsiasi entità. Gli eventi vengono attivati tramite QueryBuilder e metodi di repository/manager. Esempio:

@EventSubscriber()
export class PostSubscriber implements EntitySubscriberInterface<Post> {
/**
* Indicates that this subscriber only listen to Post events.
*/
listenTo() {
return Post
}

/**
* Called before post insertion.
*/
beforeInsert(event: InsertEvent<Post>) {
console.log(`BEFORE POST INSERTED: `, event.entity)
}
}

Puoi implementare qualsiasi metodo di EntitySubscriberInterface. Per monitorare qualsiasi entità, basta omettere il metodo listenTo e usare any:

@EventSubscriber()
export class PostSubscriber implements EntitySubscriberInterface {
/**
* Called after entity is loaded.
*/
afterLoad(entity: any) {
console.log(`AFTER ENTITY LOADED: `, entity)
}

/**
* Called before query execution.
*/
beforeQuery(event: BeforeQueryEvent<any>) {
console.log(`BEFORE QUERY: `, event.query)
}

/**
* Called after query execution.
*/
afterQuery(event: AfterQueryEvent<any>) {
console.log(`AFTER QUERY: `, event.query)
}

/**
* Called before entity insertion.
*/
beforeInsert(event: InsertEvent<any>) {
console.log(`BEFORE ENTITY INSERTED: `, event.entity)
}

/**
* Called after entity insertion.
*/
afterInsert(event: InsertEvent<any>) {
console.log(`AFTER ENTITY INSERTED: `, event.entity)
}

/**
* Called before entity update.
*/
beforeUpdate(event: UpdateEvent<any>) {
console.log(`BEFORE ENTITY UPDATED: `, event.entity)
}

/**
* Called after entity update.
*/
afterUpdate(event: UpdateEvent<any>) {
console.log(`AFTER ENTITY UPDATED: `, event.entity)
}

/**
* Called before entity removal.
*/
beforeRemove(event: RemoveEvent<any>) {
console.log(
`BEFORE ENTITY WITH ID ${event.entityId} REMOVED: `,
event.entity,
)
}

/**
* Called after entity removal.
*/
afterRemove(event: RemoveEvent<any>) {
console.log(
`AFTER ENTITY WITH ID ${event.entityId} REMOVED: `,
event.entity,
)
}

/**
* Called before entity removal.
*/
beforeSoftRemove(event: SoftRemoveEvent<any>) {
console.log(
`BEFORE ENTITY WITH ID ${event.entityId} SOFT REMOVED: `,
event.entity,
)
}

/**
* Called after entity removal.
*/
afterSoftRemove(event: SoftRemoveEvent<any>) {
console.log(
`AFTER ENTITY WITH ID ${event.entityId} SOFT REMOVED: `,
event.entity,
)
}

/**
* Called before entity recovery.
*/
beforeRecover(event: RecoverEvent<any>) {
console.log(
`BEFORE ENTITY WITH ID ${event.entityId} RECOVERED: `,
event.entity,
)
}

/**
* Called after entity recovery.
*/
afterRecover(event: RecoverEvent<any>) {
console.log(
`AFTER ENTITY WITH ID ${event.entityId} RECOVERED: `,
event.entity,
)
}

/**
* Called before transaction start.
*/
beforeTransactionStart(event: TransactionStartEvent) {
console.log(`BEFORE TRANSACTION STARTED: `, event)
}

/**
* Called after transaction start.
*/
afterTransactionStart(event: TransactionStartEvent) {
console.log(`AFTER TRANSACTION STARTED: `, event)
}

/**
* Called before transaction commit.
*/
beforeTransactionCommit(event: TransactionCommitEvent) {
console.log(`BEFORE TRANSACTION COMMITTED: `, event)
}

/**
* Called after transaction commit.
*/
afterTransactionCommit(event: TransactionCommitEvent) {
console.log(`AFTER TRANSACTION COMMITTED: `, event)
}

/**
* Called before transaction rollback.
*/
beforeTransactionRollback(event: TransactionRollbackEvent) {
console.log(`BEFORE TRANSACTION ROLLBACK: `, event)
}

/**
* Called after transaction rollback.
*/
afterTransactionRollback(event: TransactionRollbackEvent) {
console.log(`AFTER TRANSACTION ROLLBACK: `, event)
}
}

Assicurati che la proprietà subscribers sia configurata nelle tue DataSourceOptions affinché TypeORM carichi il tuo subscriber.

Event Object

Tutti i metodi di EntitySubscriberInterface, eccetto listenTo, ricevono un oggetto evento con queste proprietà di base:

  • dataSource: DataSource - DataSource utilizzata nell'evento.

  • queryRunner: QueryRunner - QueryRunner utilizzato nella transazione dell'evento.

  • manager: EntityManager - EntityManager utilizzato nella transazione dell'evento.

Consulta ogni interfaccia Evento per proprietà aggiuntive.

Nota che event.entity potrebbe non contenere le chiavi primarie quando si usa Repository.update(). Saranno disponibili solo i valori parziali forniti per l'entità. Per rendere le chiavi primarie disponibili nei subscriber, puoi passare esplicitamente i loro valori nell'oggetto entità parziale oppure usare Repository.save() che esegue un re-fetching.

await postRepository.update(post.id, { description: "Bacon ipsum dolor amet cow" })

// post.subscriber.ts
afterUpdate(event: UpdateEvent<Post>) {
console.log(event.entity) // outputs { description: 'Bacon ipsum dolor amet cow' }
}

Nota: Tutte le operazioni database nei listener di eventi sottoscritti devono essere eseguite usando l'istanza queryRunner o manager dell'oggetto evento.