Removes listeners and unsubscribes from output subscriptions
(tView: TView, lView: LView)
| 383 | |
| 384 | /** Removes listeners and unsubscribes from output subscriptions */ |
| 385 | function processCleanups(tView: TView, lView: LView): void { |
| 386 | ngDevMode && assertNotReactive(processCleanups.name); |
| 387 | const tCleanup = tView.cleanup; |
| 388 | const lCleanup = lView[CLEANUP]!; |
| 389 | if (tCleanup !== null) { |
| 390 | for (let i = 0; i < tCleanup.length - 1; i += 2) { |
| 391 | if (typeof tCleanup[i] === 'string') { |
| 392 | // This is a native DOM listener. It will occupy 4 entries in the TCleanup array (hence i += |
| 393 | // 2 at the end of this block). |
| 394 | const targetIdx = tCleanup[i + 3]; |
| 395 | ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number'); |
| 396 | if (targetIdx >= 0) { |
| 397 | // Destroy anything whose teardown is a function call (e.g. QueryList, ModelSignal). |
| 398 | lCleanup[targetIdx](); |
| 399 | } else { |
| 400 | // Subscription |
| 401 | lCleanup[-targetIdx].unsubscribe(); |
| 402 | } |
| 403 | i += 2; |
| 404 | } else { |
| 405 | // This is a cleanup function that is grouped with the index of its context |
| 406 | const context = lCleanup[tCleanup[i + 1]]; |
| 407 | tCleanup[i].call(context); |
| 408 | } |
| 409 | } |
| 410 | } |
| 411 | if (lCleanup !== null) { |
| 412 | lView[CLEANUP] = null; |
| 413 | } |
| 414 | const destroyHooks = lView[ON_DESTROY_HOOKS]; |
| 415 | if (destroyHooks !== null) { |
| 416 | // Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister |
| 417 | // themselves from mutating the array during iteration. |
| 418 | lView[ON_DESTROY_HOOKS] = null; |
| 419 | for (let i = 0; i < destroyHooks.length; i++) { |
| 420 | const destroyHooksFn = destroyHooks[i]; |
| 421 | ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.'); |
| 422 | destroyHooksFn(); |
| 423 | } |
| 424 | } |
| 425 | |
| 426 | // Destroy effects registered to the view. Many of these will have been processed above. |
| 427 | const effects = lView[EFFECTS]; |
| 428 | if (effects !== null) { |
| 429 | lView[EFFECTS] = null; |
| 430 | for (const effect of effects) { |
| 431 | effect.destroy(); |
| 432 | } |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | /** Calls onDestroy hooks for this view */ |
| 437 | function executeOnDestroys(tView: TView, lView: LView): void { |
no test coverage detected