@triniwiz/nativescript-pager
Version:
A Carousel/Pager plugin for NativeScript
370 lines (365 loc) • 16.4 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, ɵisListLikeIterable, TemplateRef, ViewContainerRef, Directive, ViewChild, Output, ContentChild, Input, InjectionToken, Inject, Host, forwardRef, Component, ChangeDetectionStrategy, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { __decorate } from 'tslib';
import { ObservableArray, isIOS, Trace, LayoutBase, profile } from '@nativescript/core';
import { registerElement, getSingleViewRecursive, isInvisibleNode } from '@nativescript/angular';
import { Pager, PagerItem, PagerLog, PagerError } from '@triniwiz/nativescript-pager';
registerElement("Pager", () => Pager);
registerElement("PagerItem", () => PagerItem);
const NG_VIEW = "_ngViewRef";
class ItemContext {
constructor($implicit, item, index, even, odd) {
this.$implicit = $implicit;
this.item = item;
this.index = index;
this.even = even;
this.odd = odd;
}
}
class TemplatedItemsComponent {
constructor(_elementRef, _iterableDiffers, zone) {
this._iterableDiffers = _iterableDiffers;
this.zone = zone;
this.setupItemView = new EventEmitter();
this.templatedItemsView = _elementRef.nativeElement;
this.templatedItemsView.on("itemLoading", this.onItemLoading, this);
this.templatedItemsView.on("itemDisposing", this.onItemDisposing, this);
}
get items() {
return this._items;
}
set items(value) {
this._items = value;
let needDiffer = true;
if (value instanceof ObservableArray) {
needDiffer = false;
}
if (needDiffer && !this._differ && ɵisListLikeIterable(value)) {
this._differ = this._iterableDiffers
.find(this._items)
.create((_index, item) => {
return item;
});
}
this.templatedItemsView.items = this._items;
}
get selectedIndex() {
return this._selectedIndex;
}
set selectedIndex(value) {
this._selectedIndex = value;
this.templatedItemsView.selectedIndex = this._selectedIndex;
}
ngAfterViewInit() {
if (!!(this._selectedIndex)) {
setTimeout(() => {
if (isIOS) {
this.templatedItemsView.scrollToIndexAnimated(this._selectedIndex, false);
}
this.templatedItemsView.selectedIndex = this._selectedIndex;
});
}
}
ngAfterContentInit() {
if (Trace.isEnabled()) {
PagerLog("TemplatedItemsView.ngAfterContentInit()");
}
this.setItemTemplates();
}
ngOnDestroy() {
this.templatedItemsView.off("itemLoading", this.onItemLoading, this);
this.templatedItemsView.off("itemDisposing", this.onItemDisposing, this);
}
setItemTemplates() {
if (!this.items)
return;
// The itemTemplateQuery may be changed after list items are added that contain <template> inside,
// so cache and use only the original template to avoid errors.
this.itemTemplate = this.itemTemplateQuery;
if (this._templateMap) {
if (Trace.isEnabled()) {
PagerLog("Setting templates");
}
const templates = [];
this._templateMap.forEach((value) => {
templates.push(value);
});
this.templatedItemsView.itemTemplates = templates;
}
}
registerTemplate(key, template) {
if (Trace.isEnabled()) {
PagerLog(`registerTemplate for key: ${key}`);
}
if (!this._templateMap) {
this._templateMap = new Map();
}
const keyedTemplate = {
key,
createView: this.getItemTemplateViewFactory(template),
};
this._templateMap.set(key, keyedTemplate);
}
onItemLoading(args) {
if (!args.view && !this.itemTemplate) {
return;
}
if (!this.items)
return;
const index = args.index;
const items = args.object.items;
const currentItem = typeof items.getItem === "function"
? items.getItem(index)
: items[index];
let viewRef;
if (args.view) {
if (Trace.isEnabled()) {
PagerLog(`onItemLoading: ${index} - Reusing existing view`);
}
viewRef = args.view[NG_VIEW];
// Getting angular view from original element (in cases when ProxyViewContainer
// is used NativeScript internally wraps it in a StackLayout)
if (!viewRef &&
args.view instanceof LayoutBase &&
args.view.getChildrenCount() > 0) {
viewRef = args.view.getChildAt(0)[NG_VIEW];
}
if (!viewRef && Trace.isEnabled()) {
PagerError(`ViewReference not found for item ${index}. View recycling is not working`);
}
}
if (!viewRef) {
if (Trace.isEnabled()) {
PagerLog(`onItemLoading: ${index} - Creating view from template`);
}
viewRef = this.loader.createEmbeddedView(this.itemTemplate, new ItemContext(), 0);
args.view = getItemViewRoot(viewRef);
args.view[NG_VIEW] = viewRef;
}
this.setupViewRef(viewRef, currentItem, index);
this.detectChangesOnChild(viewRef, index);
}
onItemDisposing(args) {
if (!args.view) {
return;
}
let viewRef;
if (args.view) {
if (Trace.isEnabled()) {
PagerLog(`onItemDisposing: ${args.index} - Removing angular view`);
}
viewRef = args.view[NG_VIEW];
// Getting angular view from original element (in cases when ProxyViewContainer
// is used NativeScript internally wraps it in a StackLayout)
if (!viewRef &&
args.view instanceof LayoutBase &&
args.view.getChildrenCount() > 0) {
viewRef = args.view.getChildAt(0)[NG_VIEW];
}
if (!viewRef && Trace.isEnabled()) {
PagerError(`ViewReference not found for item ${args.index}. View disposing is not working`);
}
}
if (viewRef) {
if (Trace.isEnabled()) {
PagerLog(`onItemDisposing: ${args.index} - Disposing view reference`);
}
viewRef.destroy();
}
}
setupViewRef(viewRef, data, index) {
const context = viewRef.context;
context.$implicit = data;
context.item = data;
context.index = index;
context.even = index % 2 === 0;
context.odd = !context.even;
this.setupItemView.next({
view: viewRef,
data: data,
index: index,
context: context,
});
}
getItemTemplateViewFactory(template) {
return () => {
const viewRef = this.loader.createEmbeddedView(template, new ItemContext(), 0);
const resultView = getItemViewRoot(viewRef);
resultView[NG_VIEW] = viewRef;
return resultView;
};
}
detectChangesOnChild(viewRef, index) {
if (Trace.isEnabled()) {
PagerLog(`Manually detect changes in child: ${index}`);
}
this.zone.run(() => {
viewRef.markForCheck();
viewRef.detectChanges();
});
}
ngDoCheck() {
if (this._differ) {
if (Trace.isEnabled()) {
PagerLog("ngDoCheck() - execute differ");
}
const changes = this._differ.diff(this._items);
if (changes) {
if (Trace.isEnabled()) {
PagerLog("ngDoCheck() - refresh");
}
this.templatedItemsView.refresh();
}
}
}
}
TemplatedItemsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplatedItemsComponent, deps: [{ token: i0.ElementRef }, { token: i0.IterableDiffers }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
TemplatedItemsComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.2", type: TemplatedItemsComponent, inputs: { items: "items", selectedIndex: "selectedIndex" }, outputs: { setupItemView: "setupItemView" }, queries: [{ propertyName: "itemTemplateQuery", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "loader", first: true, predicate: ["loader"], descendants: true, read: ViewContainerRef }], ngImport: i0 });
__decorate([
profile
], TemplatedItemsComponent.prototype, "onItemLoading", null);
__decorate([
profile
], TemplatedItemsComponent.prototype, "onItemDisposing", null);
__decorate([
profile
], TemplatedItemsComponent.prototype, "detectChangesOnChild", null);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplatedItemsComponent, decorators: [{
type: Directive
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.IterableDiffers }, { type: i0.NgZone }]; }, propDecorators: { loader: [{
type: ViewChild,
args: ["loader", { read: ViewContainerRef, static: false }]
}], setupItemView: [{
type: Output
}], itemTemplateQuery: [{
type: ContentChild,
args: [TemplateRef, { static: false }]
}], items: [{
type: Input
}], selectedIndex: [{
type: Input
}], onItemLoading: [], onItemDisposing: [], detectChangesOnChild: [] } });
function getItemViewRoot(viewRef, rootLocator = getSingleViewRecursive) {
return rootLocator(viewRef.rootNodes, 0);
}
const TEMPLATED_ITEMS_COMPONENT = new InjectionToken("TemplatedItemsComponent");
class PagerItemDirective {
constructor(templateRef, owner, viewContainer) {
this.templateRef = templateRef;
this.owner = owner;
this.viewContainer = viewContainer;
}
ensureItem() {
if (!this.item) {
this.item = new PagerItem();
}
}
applyConfig() {
this.ensureItem();
}
ngOnInit() {
this.applyConfig();
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
// Filter out text nodes and comments
const realViews = viewRef.rootNodes.filter((node) => !isInvisibleNode(node));
if (realViews.length > 0) {
const view = realViews[0];
this.item.addChild(view);
this.owner.nativeElement._addChildFromBuilder("PagerItem", this.item);
}
}
}
PagerItemDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerItemDirective, deps: [{ token: i0.TemplateRef }, { token: TEMPLATED_ITEMS_COMPONENT, host: true }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
PagerItemDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.2", type: PagerItemDirective, selector: "[pagerItem]", ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerItemDirective, decorators: [{
type: Directive,
args: [{
selector: "[pagerItem]",
}]
}], ctorParameters: function () {
return [{ type: i0.TemplateRef }, { type: TemplatedItemsComponent, decorators: [{
type: Inject,
args: [TEMPLATED_ITEMS_COMPONENT]
}, {
type: Host
}] }, { type: i0.ViewContainerRef }];
} });
class TemplateKeyDirective {
constructor(templateRef, comp) {
this.templateRef = templateRef;
this.comp = comp;
}
set pagerTemplateKey(value) {
if (this.comp && this.templateRef) {
this.comp.registerTemplate(value, this.templateRef);
}
}
}
TemplateKeyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplateKeyDirective, deps: [{ token: i0.TemplateRef }, { token: TEMPLATED_ITEMS_COMPONENT, host: true }], target: i0.ɵɵFactoryTarget.Directive });
TemplateKeyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.2", type: TemplateKeyDirective, selector: "[pagerTemplateKey]", inputs: { pagerTemplateKey: "pagerTemplateKey" }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplateKeyDirective, decorators: [{
type: Directive,
args: [{ selector: "[pagerTemplateKey]" }]
}], ctorParameters: function () {
return [{ type: i0.TemplateRef }, { type: TemplatedItemsComponent, decorators: [{
type: Inject,
args: [TEMPLATED_ITEMS_COMPONENT]
}, {
type: Host
}] }];
}, propDecorators: { pagerTemplateKey: [{
type: Input
}] } });
class PagerComponent extends TemplatedItemsComponent {
constructor(_elementRef, _iterableDiffers, zone) {
super(_elementRef, _iterableDiffers, zone);
}
get nativeElement() {
return this.templatedItemsView;
}
}
PagerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerComponent, deps: [{ token: i0.ElementRef }, { token: i0.IterableDiffers }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
PagerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.2", type: PagerComponent, selector: "Pager", providers: [
{
provide: TEMPLATED_ITEMS_COMPONENT,
useExisting: forwardRef(() => PagerComponent)
}
], usesInheritance: true, ngImport: i0, template: `
<DetachedContainer>
<Placeholder #loader></Placeholder>
</DetachedContainer>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerComponent, decorators: [{
type: Component,
args: [{
selector: 'Pager',
template: `
<DetachedContainer>
<Placeholder #loader></Placeholder>
</DetachedContainer>`,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{
provide: TEMPLATED_ITEMS_COMPONENT,
useExisting: forwardRef(() => PagerComponent)
}
]
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.IterableDiffers }, { type: i0.NgZone }]; } });
class PagerModule {
}
PagerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
PagerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.2", ngImport: i0, type: PagerModule, declarations: [PagerComponent, TemplateKeyDirective, PagerItemDirective], exports: [PagerComponent, TemplateKeyDirective, PagerItemDirective] });
PagerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerModule, decorators: [{
type: NgModule,
args: [{
declarations: [PagerComponent, TemplateKeyDirective, PagerItemDirective],
exports: [PagerComponent, TemplateKeyDirective, PagerItemDirective],
schemas: [NO_ERRORS_SCHEMA]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { PagerComponent, PagerItemDirective, PagerModule, TemplateKeyDirective, TemplatedItemsComponent };
//# sourceMappingURL=nativescript-nativescript-pager-angular.mjs.map