( effectFn: (onCleanup: EffectCleanupRegisterFn) => void, options?: CreateEffectOptions, )
| 135 | * @publicApi 20.0 |
| 136 | */ |
| 137 | export function effect( |
| 138 | effectFn: (onCleanup: EffectCleanupRegisterFn) => void, |
| 139 | options?: CreateEffectOptions, |
| 140 | ): EffectRef { |
| 141 | ngDevMode && |
| 142 | assertNotInReactiveContext( |
| 143 | effect, |
| 144 | 'Call `effect` outside of a reactive context. For example, schedule the ' + |
| 145 | 'effect inside the component constructor.', |
| 146 | ); |
| 147 | |
| 148 | if (ngDevMode && !options?.injector) { |
| 149 | assertInInjectionContext(effect); |
| 150 | } |
| 151 | |
| 152 | if (ngDevMode && options?.allowSignalWrites !== undefined) { |
| 153 | console.warn( |
| 154 | `The 'allowSignalWrites' flag is deprecated and no longer impacts effect() (writes are always allowed)`, |
| 155 | ); |
| 156 | } |
| 157 | |
| 158 | const injector = options?.injector ?? inject(Injector); |
| 159 | let destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null; |
| 160 | |
| 161 | let node: EffectNode; |
| 162 | |
| 163 | const viewContext = injector.get(ViewContext, null, {optional: true}); |
| 164 | const notifier = injector.get(ChangeDetectionScheduler); |
| 165 | if (viewContext !== null) { |
| 166 | // This effect was created in the context of a view, and will be associated with the view. |
| 167 | node = createViewEffect(viewContext.view, notifier, effectFn); |
| 168 | if (destroyRef instanceof NodeInjectorDestroyRef && destroyRef._lView === viewContext.view) { |
| 169 | // The effect is being created in the same view as the `DestroyRef` references, so it will be |
| 170 | // automatically destroyed without the need for an explicit `DestroyRef` registration. |
| 171 | destroyRef = null; |
| 172 | } |
| 173 | } else { |
| 174 | // This effect was created outside the context of a view, and will be scheduled independently. |
| 175 | node = createRootEffect(effectFn, injector.get(EffectScheduler), notifier); |
| 176 | } |
| 177 | node.injector = injector; |
| 178 | |
| 179 | if (destroyRef !== null) { |
| 180 | // If we need to register for cleanup, do that here. |
| 181 | node.onDestroyFns = [destroyRef.onDestroy(() => node.destroy())]; |
| 182 | } |
| 183 | |
| 184 | const effectRef = new EffectRefImpl(node); |
| 185 | |
| 186 | if (ngDevMode) { |
| 187 | node.debugName = options?.debugName ?? ''; |
| 188 | const prevInjectorProfilerContext = setInjectorProfilerContext({injector, token: null}); |
| 189 | try { |
| 190 | emitEffectCreatedEvent(effectRef); |
| 191 | } finally { |
| 192 | setInjectorProfilerContext(prevInjectorProfilerContext); |
| 193 | } |
| 194 | } |
no test coverage detected
searching dependent graphs…