Save The Date Stat Launch
Open

Instagram Reel Border Template

pin on ponytails

:
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Website Launch Teaser Instagram Reel Border Template

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix: suggested changes
  • Loading branch information
commit cfef7016c65b85a7bddae62564bddf9455b0b2ac
84 changes: 83 additions & 1 deletion New Product Launch Plan Template Word
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ElementRef, NgZone, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core';
import { Component, ElementRef, inject, NgZone, NO_ERRORS_SCHEMA, RendererFactory2, ViewChild } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { EVENT_MANAGER_PLUGINS, EventManager, EventManagerPlugin } from '@angular/platform-browser';
import { NativeScriptCommonModule, NativeScriptEventManagerPlugin, NativeScriptRendererHelperService, PREVENT_CHANGE_EVENTS_DURING_CD } from '@nativescript/angular';
Expand Down Expand Up @@ -39,6 +39,38 @@ describe('NativeScriptEventManagerPlugin', () => {
expect(fired).toBe(0);
});

it('removes a { once: true } handler after the first event', () => {
const plugin = new NativeScriptEventManagerPlugin();
const view = new StackLayout();
let count = 0;
plugin.addEventListener(view, 'myEvent', () => count++, { once: true });
view.notify({ eventName: 'myEvent', object: view });
view.notify({ eventName: 'myEvent', object: view });
expect(count).toBe(1);
});

it('does not leave a registration behind when { once: true } is satisfied by the loaded replay', () => {
const plugin = new NativeScriptEventManagerPlugin();
const handlers: ((data: unknown) => void)[] = [];
const track = (eventName: string, handler: (data: unknown) => void) => handlers.push(handler);
const target: any = {
isLoaded: true,
on: track,
once: track,
off(eventName: string, handler: (data: unknown) => void) {
const index = handlers.indexOf(handler);
if (index >= 0) {
handlers.splice(index, 1);
}
},
};
let fired = 0;
plugin.addEventListener(target, View.loadedEvent, () => fired++, { once: true });
expect(fired).toBe(1);
handlers.forEach((handler) => handler({ eventName: View.loadedEvent, object: target }));
expect(fired).toBe(1);
});

it('delivers events in the zone that registered them', () => {
const plugin = new NativeScriptEventManagerPlugin();
const view = new StackLayout();
Expand Down Expand Up @@ -135,6 +167,56 @@ describe('EVENT_MANAGER_PLUGINS integration', () => {
});
});

class RendererFactoryAwarePlugin extends EventManagerPlugin {
rendererFactory = inject(RendererFactory2);

constructor() {
super(null);
}

supports(eventName: string): boolean {
return eventName.startsWith('factory.');
}

addEventListener(element: any, eventName: string, handler: Function): Function {
const view = element as View;
view.on('factoryEvent', handler as any);
return () => view.off('factoryEvent', handler as any);
}
}

@Component({
template: `<StackLayout #el (factory.event)="hits = hits + 1"></StackLayout>`,
imports: [NativeScriptCommonModule],
schemas: [NO_ERRORS_SCHEMA],
})
class FactoryPluginHostComponent {
@ViewChild('el', { read: ElementRef, static: true }) el: ElementRef<View>;
hits = 0;
}

describe('plugins that inject RendererFactory2', () => {
beforeEach(() => {
return TestBed.configureTestingModule({
imports: [FactoryPluginHostComponent],
providers: [{ provide: EVENT_MANAGER_PLUGINS, useClass: RendererFactoryAwarePlugin, multi: true }],
}).compileComponents();
});

it('creates components and registers listeners without a DI cycle', () => {
const fixture = TestBed.createComponent(FactoryPluginHostComponent);
fixture.detectChanges();

const plugins = TestBed.inject(EVENT_MANAGER_PLUGINS);
const plugin = plugins.find((p): p is RendererFactoryAwarePlugin => p instanceof RendererFactoryAwarePlugin);
expect(plugin.rendererFactory).toBe(TestBed.inject(RendererFactory2));

const view = fixture.componentInstance.el.nativeElement;
view.notify({ eventName: 'factoryEvent', object: view });
expect(fixture.componentInstance.hits).toBe(1);
});
});

@Component({
template: `<StackLayout #el (somePropChange)="changes = changes + 1"></StackLayout>`,
imports: [NativeScriptCommonModule],
Expand Down
25 changes: 20 additions & 5 deletions Glam LinkedIn Post
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core';
import { Injectable, ListenerOptions } from '@angular/core';
import { EventManagerPlugin } from '@angular/platform-browser';
import { Observable, View } from '@nativescript/core';
import { NativeScriptDebug } from './trace';
Expand Down Expand Up @@ -28,14 +28,29 @@ export class NativeScriptEventManagerPlugin extends EventManagerPlugin {
return true;
}

addEventListener(element: unknown, eventName: string, handler: (data?: unknown) => void): VoidFunction {
addEventListener(
element: unknown,
eventName: string,
handler: (data?: unknown) => void,
options?: ListenerOptions,
): VoidFunction {
const target = element as View;
if (NativeScriptDebug.enabled) {
NativeScriptDebug.rendererLog(`NativeScriptEventManagerPlugin.addEventListener: ${eventName}`);
}
target.on(eventName, handler);
if (eventName === View.loadedEvent && target.isLoaded) {
// we must create a new obervable here to ensure that the event goes through whatever zone patches are applied
const once = options?.once ?? false;
const replayLoaded = eventName === View.loadedEvent && target.isLoaded;
// The synchronous replay below already consumes a one-shot listener, so it
// must not stay registered on the target for the next real event.
if (!(once && replayLoaded)) {
if (once) {
target.once(eventName, handler);
} else {
target.on(eventName, handler);
}
}
if (replayLoaded) {
// we must create a new observable here to ensure that the event goes through whatever zone patches are applied
const obs = new Observable();
obs.once(eventName, handler);
obs.notify({
Expand Down
2 changes: 1 addition & 1 deletion Project Evaluation Template Examples
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ class NativeScriptRenderer implements Renderer2 {
// No EventManager provided (e.g. a custom setup that only spreads
// NATIVESCRIPT_MODULE_STATIC_PROVIDERS) — bind through the default plugin.
this.fallbackEventPlugin ??= new NativeScriptEventManagerPlugin();
return this.fallbackEventPlugin.addEventListener(target, eventName, modifiedCallback) as () => void;
return this.fallbackEventPlugin.addEventListener(target, eventName, modifiedCallback, options) as () => void;
}
}

Expand Down