fixture.detectChange开始单步调试,如何执行到Directive的ngAfterViewInit钩子
2023-09-14 09:04:02 时间
同ngOnChanges hook的调用入口一致,请查看这篇文章:fixture.detectChange开始单步调试,如何执行到Directive的ngOnChange钩子.
refreshView是一个逻辑很多的函数:
/**
* Processes a view in update mode. This includes a number of steps in a specific order:
* - executing a template function in update mode;
* - executing hooks;
* - refreshing queries;
* - setting host bindings;
* - refreshing child (embedded and component) views.
*/
function refreshView(tView, lView, templateFn, context) {
ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode');
const flags = lView[FLAGS];
if ((flags & 256 /* Destroyed */) === 256 /* Destroyed */)
return;
enterView(lView, lView[T_HOST]);
const checkNoChangesMode = getCheckNoChangesMode();
try {
resetPreOrderHookFlags(lView);
setBindingIndex(tView.bindingStartIndex);
if (templateFn !== null) {
executeTemplate(tView, lView, templateFn, 2 /* Update */, context);
}
const hooksInitPhaseCompleted = (flags & 3 /* InitPhaseStateMask */) === 3 /* InitPhaseCompleted */;
// execute pre-order hooks (OnInit, OnChanges, DoCheck)
// PERF WARNING: do NOT extract this to a separate function without running benchmarks
if (!checkNoChangesMode) {
if (hooksInitPhaseCompleted) {
const preOrderCheckHooks = tView.preOrderCheckHooks;
if (preOrderCheckHooks !== null) {
executeCheckHooks(lView, preOrderCheckHooks, null);
}
}
else {
const preOrderHooks = tView.preOrderHooks;
if (preOrderHooks !== null) {
executeInitAndCheckHooks(lView, preOrderHooks, 0 /* OnInitHooksToBeRun */, null);
}
incrementInitPhaseFlags(lView, 0 /* OnInitHooksToBeRun */);
}
}
// First mark transplanted views that are declared in this lView as needing a refresh at their
// insertion points. This is needed to avoid the situation where the template is defined in this
// `LView` but its declaration appears after the insertion component.
markTransplantedViewsForRefresh(lView);
refreshEmbeddedViews(lView);
// Content query results must be refreshed before content hooks are called.
if (tView.contentQueries !== null) {
refreshContentQueries(tView, lView);
}
// execute content hooks (AfterContentInit, AfterContentChecked)
// PERF WARNING: do NOT extract this to a separate function without running benchmarks
if (!checkNoChangesMode) {
if (hooksInitPhaseCompleted) {
const contentCheckHooks = tView.contentCheckHooks;
if (contentCheckHooks !== null) {
executeCheckHooks(lView, contentCheckHooks);
}
}
else {
const contentHooks = tView.contentHooks;
if (contentHooks !== null) {
executeInitAndCheckHooks(lView, contentHooks, 1 /* AfterContentInitHooksToBeRun */);
}
incrementInitPhaseFlags(lView, 1 /* AfterContentInitHooksToBeRun */);
}
}
setHostBindingsByExecutingExpandoInstructions(tView, lView);
// Refresh child component views.
const components = tView.components;
if (components !== null) {
refreshChildComponents(lView, components);
}
// View queries must execute after refreshing child components because a template in this view
// could be inserted in a child component. If the view query executes before child component
// refresh, the template might not yet be inserted.
const viewQuery = tView.viewQuery;
if (viewQuery !== null) {
executeViewQueryFn(2 /* Update */, viewQuery, context);
}
// execute view hooks (AfterViewInit, AfterViewChecked)
// PERF WARNING: do NOT extract this to a separate function without running benchmarks
if (!checkNoChangesMode) {
if (hooksInitPhaseCompleted) {
const viewCheckHooks = tView.viewCheckHooks;
if (viewCheckHooks !== null) {
executeCheckHooks(lView, viewCheckHooks);
}
}
else {
const viewHooks = tView.viewHooks;
if (viewHooks !== null) {
executeInitAndCheckHooks(lView, viewHooks, 2 /* AfterViewInitHooksToBeRun */);
}
incrementInitPhaseFlags(lView, 2 /* AfterViewInitHooksToBeRun */);
}
}
if (tView.firstUpdatePass === true) {
// We need to make sure that we only flip the flag on successful `refreshView` only
// Don't do this in `finally` block.
// If we did this in `finally` block then an exception could block the execution of styling
// instructions which in turn would be unable to insert themselves into the styling linked
// list. The result of this would be that if the exception would not be throw on subsequent CD
// the styling would be unable to process it data and reflect to the DOM.
tView.firstUpdatePass = false;
}
// Do not reset the dirty state when running in check no changes mode. We don't want components
// to behave differently depending on whether check no changes is enabled or not. For example:
// Marking an OnPush component as dirty from within the `ngAfterViewInit` hook in order to
// refresh a `NgClass` binding should work. If we would reset the dirty state in the check
// no changes cycle, the component would be not be dirty for the next update pass. This would
// be different in production mode where the component dirty state is not reset.
if (!checkNoChangesMode) {
lView[FLAGS] &= ~(64 /* Dirty */ | 8 /* FirstLViewPass */);
}
if (lView[FLAGS] & 1024 /* RefreshTransplantedView */) {
lView[FLAGS] &= ~1024 /* RefreshTransplantedView */;
updateTransplantedViewCount(lView[PARENT], -1);
}
}
finally {
leaveView();
}
}
从refreshView函数调用hook的顺序来看,ngOnChanges hook的执行一定先于ngAfterViewInit:
相关文章
- cy.visit 执行逻辑的单步调试
- 全志A40i开发板——串口调试助手实现
- ActionScript项目无法调试[通俗易懂]
- kubeSphere自带镜像底包pod远程调试
- linux phy调试方法_php执行shell命令
- pycharm如何调试python程序_Pycharm断点调试Python程序的步骤方法
- HTTPS调试中自签名证书错误ERR_CERT_COMMON_NAME_INVALID的解决方法
- 通过调试理解EVM #3 :存储布局如何工作?
- GDB后台(异步)执行调试命令
- 在Linux系统上使用QT和GDB调试(qtlinuxgdb)
- 使用c Linux调试工具简化开发流程(clinux调试工具)
- 浅谈被加壳ELF的调试
- 深入探索Oracle的10046调试跟踪功能(oracle的10046)
- 了解Linux的几种模式:掌握系统配置与调试方法(linux几种模式)
- GDB: Linux系统中的强大调试工具(gdblinux)
- asp.net程序编译调试时偶尔出现访问被拒绝的错误的解决方法
- PHP性能优化工具篇Benchmark类调试执行时间
- 解析使用ThinkPHP应该掌握的调试手段
- Yii框架在页面输出执行sql语句以方便调试的实现方法