@nativescript-community/ui-collectionview
Version:
Allows you to easily add a collection view (grid list view) to your projects. Supports vertical and horizontal modes, templating, and more.
104 lines • 3.87 kB
JavaScript
import { Observable, ObservableArray } from '@nativescript/core';
const VUE_VIEW = '__vueVNodeRef__';
export default {
props: {
items: {
validator: (val) => !val || Array.isArray(val) || val instanceof ObservableArray,
required: true
},
'+alias': {
type: String,
default: 'item'
},
'+index': {
type: String
},
itemTemplateSelector: {
type: Function,
default: undefined
}
},
template: `<NativeCollectionView ref="listView" :items="items" v-bind="$attrs" v-on="listeners" ="onItemTap" ="onItemLoadingInternal" ="onItemDisposingInternal"
>
<slot /></NativeCollectionView>`,
watch: {
items: {
handler(newVal, oldVal) {
if (!(oldVal instanceof Observable)) {
this.$refs.listView.setAttribute('items', newVal);
}
},
deep: true
}
},
created() {
// we need to remove the itemTap handler from a clone of the $listeners
// object because we are emitting the event ourselves with added data.
const listeners = Object.assign({}, this.$listeners);
delete listeners.itemTap;
this.listeners = listeners;
this.getItemContext = getItemContext.bind(this);
},
mounted() {
const listView = this.$refs.listView;
this.listView = listView.nativeView;
listView.setAttribute('itemTemplates', this.$templates.getKeyedTemplates());
const itemTemplateSelector = this.itemTemplateSelector
? this.itemTemplateSelector // custom template selector if any
: (item, index, items) => this.$templates.selectorFn(this.getItemContext(item, index));
listView.setAttribute('itemTemplateSelector', itemTemplateSelector);
},
methods: {
getItem(index) {
return this.listView.getItemAtIndex(index);
},
onItemTap(args) {
this.$emit('itemTap', { item: this.getItem(args.index), ...args });
},
updateViewTemplate(args) {
const listView = args.object;
const index = args.index;
const items = args.object.items;
const currentItem = args.bindingContext;
const name = listView._itemTemplateSelector(currentItem, index, items);
const context = this.getItemContext(currentItem, index);
const oldVnode = args.view?.[VUE_VIEW];
if (args.view) {
args.view._batchUpdate(() => {
args.view = this.$templates.patchTemplate(name, context, oldVnode);
});
}
else {
args.view = this.$templates.patchTemplate(name, context, oldVnode);
}
},
onItemLoadingInternal(args) {
this.updateViewTemplate(args);
},
onItemDisposingInternal(args) {
const oldVnode = args.view && args.view[VUE_VIEW];
if (oldVnode) {
// properly dispose the oldVnode (this will unmount the tree)
this.__patch__(oldVnode, null);
}
},
refresh() {
this.listView.refresh();
},
scrollToIndex(index, animate = false) {
this.listView.scrollToIndex(index, animate);
}
// getSelectedItems() {
// return (this.listView as CollectionView).getSelectedItems();
// }
}
};
function getItemContext(item, index = -1, alias = this.$props['+alias'], index_alias = this.$props['+index']) {
return {
[alias]: item,
[index_alias || '$index']: index,
$even: index % 2 === 0,
$odd: index % 2 !== 0
};
}
//# sourceMappingURL=component.js.map