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