UNPKG

@angular/core

Version:

Angular - the core framework

98 lines 15.7 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { createComputed, SIGNAL } from '@angular/core/primitives/signals'; import { RuntimeError } from '../errors'; import { unwrapElementRef } from '../linker/element_ref'; import { EMPTY_ARRAY } from '../util/empty'; import { FLAGS } from './interfaces/view'; import { getQueryResults, loadQueryInternal } from './query'; import { signal } from './reactivity/signal'; import { getLView } from './state'; /** * A signal factory function in charge of creating a new computed signal capturing query * results. This centralized creation function is used by all types of queries (child / children, * required / optional). * * @param firstOnly indicates if all or only the first result should be returned * @param required indicates if at least one result is required * @returns a read-only signal with query results */ function createQuerySignalFn(firstOnly, required) { let node; const signalFn = createComputed(() => { // A dedicated signal that increments its value every time a query changes its dirty status. By // using this signal we can implement a query as computed and avoid creation of a specialized // reactive node type. Please note that a query gets marked dirty under the following // circumstances: // - a view (where a query is active) finished its first creation pass; // - a new view is inserted / deleted and it impacts query results. node._dirtyCounter(); const value = refreshSignalQuery(node, firstOnly); if (required && value === undefined) { throw new RuntimeError(-951 /* RuntimeErrorCode.REQUIRED_QUERY_NO_VALUE */, ngDevMode && 'Child query result is required but no value is available.'); } return value; }); node = signalFn[SIGNAL]; node._dirtyCounter = signal(0); node._flatValue = undefined; if (ngDevMode) { signalFn.toString = () => `[Query Signal]`; } return signalFn; } export function createSingleResultOptionalQuerySignalFn() { return createQuerySignalFn(/* firstOnly */ true, /* required */ false); } export function createSingleResultRequiredQuerySignalFn() { return createQuerySignalFn(/* firstOnly */ true, /* required */ true); } export function createMultiResultQuerySignalFn() { return createQuerySignalFn(/* firstOnly */ false, /* required */ false); } export function bindQueryToSignal(target, queryIndex) { const node = target[SIGNAL]; node._lView = getLView(); node._queryIndex = queryIndex; node._queryList = loadQueryInternal(node._lView, queryIndex); node._queryList.onDirty(() => node._dirtyCounter.update((v) => v + 1)); } function refreshSignalQuery(node, firstOnly) { const lView = node._lView; const queryIndex = node._queryIndex; // There are 2 conditions under which we want to return "empty" results instead of the ones // collected by a query: // // 1) a given query wasn't created yet (this is a period of time between the directive creation // and execution of the query creation function) - in this case a query doesn't exist yet and we // don't have any results to return. // // 2) we are in the process of constructing a view (the first // creation pass didn't finish) and a query might have partial results, but we don't want to // return those - instead we do delay results collection until all nodes had a chance of matching // and we can present consistent, "atomic" (on a view level) results. if (lView === undefined || queryIndex === undefined || lView[FLAGS] & 4 /* LViewFlags.CreationMode */) { return (firstOnly ? undefined : EMPTY_ARRAY); } const queryList = loadQueryInternal(lView, queryIndex); const results = getQueryResults(lView, queryIndex); queryList.reset(results, unwrapElementRef); if (firstOnly) { return queryList.first; } else { // TODO: remove access to the private _changesDetected field by abstracting / removing usage of // QueryList in the signal-based queries (perf follow-up) const resultChanged = queryList._changesDetected; if (resultChanged || node._flatValue === undefined) { return (node._flatValue = queryList.toArray()); } return node._flatValue; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnlfcmVhY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL3F1ZXJ5X3JlYWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBZSxjQUFjLEVBQUUsTUFBTSxFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFdEYsT0FBTyxFQUFDLFlBQVksRUFBbUIsTUFBTSxXQUFXLENBQUM7QUFDekQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFFdkQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUUxQyxPQUFPLEVBQUMsS0FBSyxFQUFvQixNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sRUFBQyxlQUFlLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFM0QsT0FBTyxFQUFDLE1BQU0sRUFBaUIsTUFBTSxxQkFBcUIsQ0FBQztBQUMzRCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBY2pDOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBSSxTQUFrQixFQUFFLFFBQWlCO0lBQ25FLElBQUksSUFBd0IsQ0FBQztJQUM3QixNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsR0FBRyxFQUFFO1FBQ25DLCtGQUErRjtRQUMvRiw2RkFBNkY7UUFDN0YscUZBQXFGO1FBQ3JGLGlCQUFpQjtRQUNqQix1RUFBdUU7UUFDdkUsbUVBQW1FO1FBQ25FLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQixNQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBSSxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFckQsSUFBSSxRQUFRLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxZQUFZLHNEQUVwQixTQUFT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RUFBRSxDQUFDO1lBQ25ELE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtDb21wdXRlZE5vZGUsIGNyZWF0ZUNvbXB1dGVkLCBTSUdOQUx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcHJpbWl0aXZlcy9zaWduYWxzJztcblxuaW1wb3J0IHtSdW50aW1lRXJyb3IsIFJ1bnRpbWVFcnJvckNvZGV9IGZyb20gJy4uL2Vycm9ycyc7XG5pbXBvcnQge3Vud3JhcEVsZW1lbnRSZWZ9IGZyb20gJy4uL2xpbmtlci9lbGVtZW50X3JlZic7XG5pbXBvcnQge1F1ZXJ5TGlzdH0gZnJvbSAnLi4vbGlua2VyL3F1ZXJ5X2xpc3QnO1xuaW1wb3J0IHtFTVBUWV9BUlJBWX0gZnJvbSAnLi4vdXRpbC9lbXB0eSc7XG5cbmltcG9ydCB7RkxBR1MsIExWaWV3LCBMVmlld0ZsYWdzfSBmcm9tICcuL2ludGVyZmFjZXMvdmlldyc7XG5pbXBvcnQge2dldFF1ZXJ5UmVzdWx0cywgbG9hZFF1ZXJ5SW50ZXJuYWx9IGZyb20gJy4vcXVlcnknO1xuaW1wb3J0IHtTaWduYWx9IGZyb20gJy4vcmVhY3Rpdml0eS9hcGknO1xuaW1wb3J0IHtzaWduYWwsIFdyaXRhYmxlU2lnbmFsfSBmcm9tICcuL3JlYWN0aXZpdHkvc2lnbmFsJztcbmltcG9ydCB7Z2V0TFZpZXd9IGZyb20gJy4vc3RhdGUnO1xuXG5pbnRlcmZhY2UgUXVlcnlTaWduYWxOb2RlPFQ+IGV4dGVuZHMgQ29tcHV0ZWROb2RlPFQgfCBSZWFkb25seUFycmF5PFQ+PiB7XG4gIF9sVmlldz86IExWaWV3O1xuICBfcXVlcnlJbmRleD86IG51bWJlcjtcbiAgX3F1ZXJ5TGlzdD86IFF1ZXJ5TGlzdDxUPjtcbiAgX2RpcnR5Q291bnRlcjogV3JpdGFibGVTaWduYWw8bnVtYmVyPjtcbiAgLyoqXG4gICAqIFN0b3JlcyB0aGUgbGFzdCBzZWVuLCBmbGF0dGVuZWQgcmVzdWx0cyBmb3IgYSBxdWVyeS4gVGhpcyBpcyB0byBhdm9pZCBtYXJraW5nIHRoZSBzaWduYWwgcmVzdWx0XG4gICAqIGNvbXB1dGVkIGFzIGRpcnR5IHdoZW4gdGhlcmUgd2FzIHZpZXcgbWFuaXB1bGF0aW9uIHRoYXQgZGlkbid0IGltcGFjdCBmaW5hbCByZXN1bHRzLlxuICAgKi9cbiAgX2ZsYXRWYWx1ZT86IFQgfCBSZWFkb25seUFycmF5PFQ+O1xufVxuXG4vKipcbiAqIEEgc2lnbmFsIGZhY3RvcnkgZnVuY3Rpb24gaW4gY2hhcmdlIG9mIGNyZWF0aW5nIGEgbmV3IGNvbXB1dGVkIHNpZ25hbCBjYXB0dXJpbmcgcXVlcnlcbiAqIHJlc3VsdHMuIFRoaXMgY2VudHJhbGl6ZWQgY3JlYXRpb24gZnVuY3Rpb24gaXMgdXNlZCBieSBhbGwgdHlwZXMgb2YgcXVlcmllcyAoY2hpbGQgLyBjaGlsZHJlbixcbiAqIHJlcXVpcmVkIC8gb3B0aW9uYWwpLlxuICpcbiAqIEBwYXJhbSBmaXJzdE9ubHkgaW5kaWNhdGVzIGlmIGFsbCBvciBvbmx5IHRoZSBmaXJzdCByZXN1bHQgc2hvdWxkIGJlIHJldHVybmVkXG4gKiBAcGFyYW0gcmVxdWlyZWQgaW5kaWNhdGVzIGlmIGF0IGxlYXN0IG9uZSByZXN1bHQgaXMgcmVxdWlyZWRcbiAqIEByZXR1cm5zIGEgcmVhZC1vbmx5IHNpZ25hbCB3aXRoIHF1ZXJ5IHJlc3VsdHNcbiAqL1xuZnVuY3Rpb24gY3JlYXRlUXVlcnlTaWduYWxGbjxWPihmaXJzdE9ubHk6IGJvb2xlYW4sIHJlcXVpcmVkOiBib29sZWFuKSB7XG4gIGxldCBub2RlOiBRdWVyeVNpZ25hbE5vZGU8Vj47XG4gIGNvbnN0IHNpZ25hbEZuID0gY3JlYXRlQ29tcHV0ZWQoKCkgPT4ge1xuICAgIC8vIEEgZGVkaWNhdGVkIHNpZ25hbCB0aGF0IGluY3JlbWVudHMgaXRzIHZhbHVlIGV2ZXJ5IHRpbWUgYSBxdWVyeSBjaGFuZ2VzIGl0cyBkaXJ0eSBzdGF0dXMuIEJ5XG4gICAgLy8gdXNpbmcgdGhpcyBzaWduYWwgd2UgY2FuIGltcGxlbWVudCBhIHF1ZXJ5IGFzIGNvbXB1dGVkIGFuZCBhdm9pZCBjcmVhdGlvbiBvZiBhIHNwZWNpYWxpemVkXG4gICAgLy8gcmVhY3RpdmUgbm9kZSB0eXBlLiBQbGVhc2Ugbm90ZSB0aGF0IGEgcXVlcnkgZ2V0cyBtYXJrZWQgZGlydHkgdW5kZXIgdGhlIGZvbGxvd2luZ1xuICAgIC8vIGNpcmN1bXN0YW5jZXM6XG4gICAgLy8gLSBhIHZpZXcgKHdoZXJlIGEgcXVlcnkgaXMgYWN0aXZlKSBmaW5pc2hlZCBpdHMgZmlyc3QgY3JlYXRpb24gcGFzcztcbiAgICAvLyAtIGEgbmV3IHZpZXcgaXMgaW5zZXJ0ZWQgLyBkZWxldGVkIGFuZCBpdCBpbXBhY3RzIHF1ZXJ5IHJlc3VsdHMuXG4gICAgbm9kZS5fZGlydHlDb3VudGVyKCk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IHJlZnJlc2hTaWduYWxRdWVyeTxWPihub2RlLCBmaXJzdE9ubHkpO1xuXG4gICAgaWYgKHJlcXVpcmVkICYmIHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuUkVRVUlSRURfUVVFUllfTk9fVkFMVUUsXG4gICAgICAgIG5nRGV2TW9kZSAmJiAnQ2hpbGQgcXVlcnkgcmVzdWx0IGlzIHJlcXVpcmVkIGJ1dCBubyB2YWx1ZSBpcyBhdmFpbGFibGUuJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9KTtcbiAgbm9kZSA9IHNpZ25hbEZuW1NJR05BTF0gYXMgUXVlcnlTaWduYWxOb2RlPFY+O1xuICBub2RlLl9kaXJ0eUNvdW50ZXIgPSBzaWduYWwoMCk7XG4gIG5vZGUuX2ZsYXRWYWx1ZSA9IHVuZGVmaW5lZDtcblxuICBpZiAobmdEZXZNb2RlKSB7XG4gICAgc2lnbmFsRm4udG9TdHJpbmcgPSAoKSA9PiBgW1F1ZXJ5IFNpZ25hbF1gO1xuICB9XG5cbiAgcmV0dXJuIHNpZ25hbEZuO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2luZ2xlUmVzdWx0T3B0aW9uYWxRdWVyeVNpZ25hbEZuPFJlYWRUPigpOiBTaWduYWw8UmVhZFQgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIGNyZWF0ZVF1ZXJ5U2lnbmFsRm4oLyogZmlyc3RPbmx5ICovIHRydWUsIC8qIHJlcXVpcmVkICovIGZhbHNlKSBhcyBTaWduYWw8XG4gICAgUmVhZFQgfCB1bmRlZmluZWRcbiAgPjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNpbmdsZVJlc3VsdFJlcXVpcmVkUXVlcnlTaWduYWxGbjxSZWFkVD4oKTogU2lnbmFsPFJlYWRUPiB7XG4gIHJldHVybiBjcmVhdGVRdWVyeVNpZ25hbEZuKC8qIGZpcnN0T25seSAqLyB0cnVlLCAvKiByZXF1aXJlZCAqLyB0cnVlKSBhcyBTaWduYWw8UmVhZFQ+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTXVsdGlSZXN1bHRRdWVyeVNpZ25hbEZuPFJlYWRUPigpOiBTaWduYWw8UmVhZG9ubHlBcnJheTxSZWFkVD4+IHtcbiAgcmV0dXJuIGNyZWF0ZVF1ZXJ5U2lnbmFsRm4oLyogZmlyc3RPbmx5ICovIGZhbHNlLCAvKiByZXF1aXJlZCAqLyBmYWxzZSkgYXMgU2lnbmFsPFxuICAgIFJlYWRvbmx5QXJyYXk8UmVhZFQ+XG4gID47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBiaW5kUXVlcnlUb1NpZ25hbCh0YXJnZXQ6IFNpZ25hbDx1bmtub3duPiwgcXVlcnlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gIGNvbnN0IG5vZGUgPSB0YXJnZXRbU0lHTkFMXSBhcyBRdWVyeVNpZ25hbE5vZGU8dW5rbm93bj47XG4gIG5vZGUuX2xWaWV3ID0gZ2V0TFZpZXcoKTtcbiAgbm9kZS5fcXVlcnlJbmRleCA9IHF1ZXJ5SW5kZXg7XG4gIG5vZGUuX3F1ZXJ5TGlzdCA9IGxvYWRRdWVyeUludGVybmFsKG5vZGUuX2xWaWV3LCBxdWVyeUluZGV4KTtcbiAgbm9kZS5fcXVlcnlMaXN0Lm9uRGlydHkoKCkgPT4gbm9kZS5fZGlydHlDb3VudGVyLnVwZGF0ZSgodikgPT4gdiArIDEpKTtcbn1cblxuZnVuY3Rpb24gcmVmcmVzaFNpZ25hbFF1ZXJ5PFY+KG5vZGU6IFF1ZXJ5U2lnbmFsTm9kZTxWPiwgZmlyc3RPbmx5OiBib29sZWFuKTogViB8IFJlYWRvbmx5QXJyYXk8Vj4ge1xuICBjb25zdCBsVmlldyA9IG5vZGUuX2xWaWV3O1xuICBjb25zdCBxdWVyeUluZGV4ID0gbm9kZS5fcXVlcnlJbmRleDtcblxuICAvLyBUaGVyZSBhcmUgMiBjb25kaXRpb25zIHVuZGVyIHdoaWNoIHdlIHdhbnQgdG8gcmV0dXJuIFwiZW1wdHlcIiByZXN1bHRzIGluc3RlYWQgb2YgdGhlIG9uZXNcbiAgLy8gY29sbGVjdGVkIGJ5IGEgcXVlcnk6XG4gIC8vXG4gIC8vIDEpIGEgZ2l2ZW4gcXVlcnkgd2Fzbid0IGNyZWF0ZWQgeWV0ICh0aGlzIGlzIGEgcGVyaW9kIG9mIHRpbWUgYmV0d2VlbiB0aGUgZGlyZWN0aXZlIGNyZWF0aW9uXG4gIC8vIGFuZCBleGVjdXRpb24gb2YgdGhlIHF1ZXJ5IGNyZWF0aW9uIGZ1bmN0aW9uKSAtIGluIHRoaXMgY2FzZSBhIHF1ZXJ5IGRvZXNuJ3QgZXhpc3QgeWV0IGFuZCB3ZVxuICAvLyBkb24ndCBoYXZlIGFueSByZXN1bHRzIHRvIHJldHVybi5cbiAgLy9cbiAgLy8gMikgd2UgYXJlIGluIHRoZSBwcm9jZXNzIG9mIGNvbnN0cnVjdGluZyBhIHZpZXcgKHRoZSBmaXJzdFxuICAvLyBjcmVhdGlvbiBwYXNzIGRpZG4ndCBmaW5pc2gpIGFuZCBhIHF1ZXJ5IG1pZ2h0IGhhdmUgcGFydGlhbCByZXN1bHRzLCBidXQgd2UgZG9uJ3Qgd2FudCB0b1xuICAvLyByZXR1cm4gdGhvc2UgLSBpbnN0ZWFkIHdlIGRvIGRlbGF5IHJlc3VsdHMgY29sbGVjdGlvbiB1bnRpbCBhbGwgbm9kZXMgaGFkIGEgY2hhbmNlIG9mIG1hdGNoaW5nXG4gIC8vIGFuZCB3ZSBjYW4gcHJlc2VudCBjb25zaXN0ZW50LCBcImF0b21pY1wiIChvbiBhIHZpZXcgbGV2ZWwpIHJlc3VsdHMuXG4gIGlmIChsVmlldyA9PT0gdW5kZWZpbmVkIHx8IHF1ZXJ5SW5kZXggPT09IHVuZGVmaW5lZCB8fCBsVmlld1tGTEFHU10gJiBMVmlld0ZsYWdzLkNyZWF0aW9uTW9kZSkge1xuICAgIHJldHVybiAoZmlyc3RPbmx5ID8gdW5kZWZpbmVkIDogRU1QVFlfQVJSQVkpIGFzIFY7XG4gIH1cblxuICBjb25zdCBxdWVyeUxpc3QgPSBsb2FkUXVlcnlJbnRlcm5hbDxWPihsVmlldywgcXVlcnlJbmRleCk7XG4gIGNvbnN0IHJlc3VsdHMgPSBnZXRRdWVyeVJlc3VsdHM8Vj4obFZpZXcsIHF1ZXJ5SW5kZXgpO1xuXG4gIHF1ZXJ5TGlzdC5yZXNldChyZXN1bHRzLCB1bndyYXBFbGVtZW50UmVmKTtcblxuICBpZiAoZmlyc3RPbmx5KSB7XG4gICAgcmV0dXJuIHF1ZXJ5TGlzdC5maXJzdDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUT0RPOiByZW1vdmUgYWNjZXNzIHRvIHRoZSBwcml2YXRlIF9jaGFuZ2VzRGV0ZWN0ZWQgZmllbGQgYnkgYWJzdHJhY3RpbmcgLyByZW1vdmluZyB1c2FnZSBvZlxuICAgIC8vIFF1ZXJ5TGlzdCBpbiB0aGUgc2lnbmFsLWJhc2VkIHF1ZXJpZXMgKHBlcmYgZm9sbG93LXVwKVxuICAgIGNvbnN0IHJlc3VsdENoYW5nZWQgPSAocXVlcnlMaXN0IGFzIGFueSBhcyB7X2NoYW5nZXNEZXRlY3RlZDogYm9vbGVhbn0pLl9jaGFuZ2VzRGV0ZWN0ZWQ7XG4gICAgaWYgKHJlc3VsdENoYW5nZWQgfHwgbm9kZS5fZmxhdFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAobm9kZS5fZmxhdFZhbHVlID0gcXVlcnlMaXN0LnRvQXJyYXkoKSk7XG4gICAgfVxuICAgIHJldHVybiBub2RlLl9mbGF0VmFsdWU7XG4gIH1cbn1cbiJdfQ==