mirror of https://github.com/artf/grapesjs.git
14 changed files with 689 additions and 465 deletions
@ -1,4 +1,4 @@ |
|||
export { default as Model } from './Model'; |
|||
export { default as Collection } from './Collection'; |
|||
export { default as View } from './View'; |
|||
export { default as Module } from './moduleLegacy'; |
|||
export { default as Module } from './Module'; |
|||
|
|||
@ -1,47 +0,0 @@ |
|||
import { bindAll } from 'underscore'; |
|||
import { Collection } from '../../common'; |
|||
import Frame from './Frame'; |
|||
|
|||
export default class Frames extends Collection { |
|||
initialize(models, config = {}) { |
|||
bindAll(this, 'itemLoaded'); |
|||
this.config = config; |
|||
this.on('reset', this.onReset); |
|||
this.on('remove', this.onRemove); |
|||
} |
|||
|
|||
onReset(m, opts = {}) { |
|||
const prev = opts.previousModels || []; |
|||
prev.map(p => this.onRemove(p)); |
|||
} |
|||
|
|||
onRemove(removed) { |
|||
removed && removed.onRemove(); |
|||
} |
|||
|
|||
itemLoaded() { |
|||
this.loadedItems++; |
|||
|
|||
if (this.loadedItems >= this.itemsToLoad) { |
|||
this.trigger('loaded:all'); |
|||
this.listenToLoadItems(0); |
|||
} |
|||
} |
|||
|
|||
listenToLoad() { |
|||
this.loadedItems = 0; |
|||
this.itemsToLoad = this.length; |
|||
this.listenToLoadItems(1); |
|||
} |
|||
|
|||
listenToLoadItems(on) { |
|||
this.forEach(item => item[on ? 'on' : 'off']('loaded', this.itemLoaded)); |
|||
} |
|||
|
|||
add(m, o = {}) { |
|||
const { config } = this; |
|||
return Collection.prototype.add.call(this, m, { ...o, config }); |
|||
} |
|||
} |
|||
|
|||
Frames.prototype.model = Frame; |
|||
@ -0,0 +1,45 @@ |
|||
import { bindAll } from 'underscore'; |
|||
import { Collection } from '../../common'; |
|||
import Page from '../../pages/model/Page'; |
|||
import Frame from './Frame'; |
|||
|
|||
export default class Frames extends Collection<Frame> { |
|||
loadedItems = 0; |
|||
itemsToLoad = 0; |
|||
page?: Page; |
|||
|
|||
constructor(models?: Frame[]) { |
|||
super(models); |
|||
bindAll(this, 'itemLoaded'); |
|||
this.on('reset', this.onReset); |
|||
this.on('remove', this.onRemove); |
|||
} |
|||
|
|||
onReset(m: Frame, opts?: { previousModels?: Frame[] }) { |
|||
const prev = opts?.previousModels || []; |
|||
prev.map((p) => this.onRemove(p)); |
|||
} |
|||
|
|||
onRemove(removed?: Frame) { |
|||
removed?.onRemove(); |
|||
} |
|||
|
|||
itemLoaded() { |
|||
this.loadedItems++; |
|||
|
|||
if (this.loadedItems >= this.itemsToLoad) { |
|||
this.trigger('loaded:all'); |
|||
this.listenToLoadItems(false); |
|||
} |
|||
} |
|||
|
|||
listenToLoad() { |
|||
this.loadedItems = 0; |
|||
this.itemsToLoad = this.length; |
|||
this.listenToLoadItems(true); |
|||
} |
|||
|
|||
listenToLoadItems(on: boolean) { |
|||
this.forEach((item) => item[on ? 'on' : 'off']('loaded', this.itemLoaded)); |
|||
} |
|||
} |
|||
@ -1,299 +0,0 @@ |
|||
/** |
|||
* You can customize the initial state of the module from the editor initialization |
|||
* ```js
|
|||
* const editor = grapesjs.init({ |
|||
* .... |
|||
* pageManager: { |
|||
* pages: [ |
|||
* { |
|||
* id: 'page-id', |
|||
* styles: `.my-class { color: red }`, // or a JSON of styles
|
|||
* component: '<div class="my-class">My element</div>', // or a JSON of components
|
|||
* } |
|||
* ] |
|||
* }, |
|||
* }) |
|||
* ``` |
|||
* |
|||
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance |
|||
* |
|||
* ```js
|
|||
* const pageManager = editor.Pages; |
|||
* ``` |
|||
* |
|||
* ## Available Events |
|||
* * `page:add` - Added new page. The page is passed as an argument to the callback |
|||
* * `page:remove` - Page removed. The page is passed as an argument to the callback |
|||
* * `page:select` - New page selected. The newly selected page and the previous one, are passed as arguments to the callback |
|||
* * `page:update` - Page updated. The updated page and the object containing changes are passed as arguments to the callback |
|||
* * `page` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback |
|||
* |
|||
* ## Methods |
|||
* * [add](#add) |
|||
* * [get](#get) |
|||
* * [getAll](#getall) |
|||
* * [getAllWrappers](#getallwrappers) |
|||
* * [getMain](#getmain) |
|||
* * [remove](#remove) |
|||
* * [select](#select) |
|||
* * [getSelected](#getselected) |
|||
* |
|||
* [Page]: page.html |
|||
* [Component]: component.html |
|||
* |
|||
* @module Pages |
|||
*/ |
|||
|
|||
import { isString, bindAll, unique, flatten } from 'underscore'; |
|||
import { createId } from '../utils/mixins'; |
|||
import { Model, Module } from '../common'; |
|||
import Pages from './model/Pages'; |
|||
import Page from './model/Page'; |
|||
|
|||
export const evAll = 'page'; |
|||
export const evPfx = `${evAll}:`; |
|||
export const evPageSelect = `${evPfx}select`; |
|||
export const evPageSelectBefore = `${evPageSelect}:before`; |
|||
export const evPageUpdate = `${evPfx}update`; |
|||
export const evPageAdd = `${evPfx}add`; |
|||
export const evPageAddBefore = `${evPageAdd}:before`; |
|||
export const evPageRemove = `${evPfx}remove`; |
|||
export const evPageRemoveBefore = `${evPageRemove}:before`; |
|||
const chnSel = 'change:selected'; |
|||
const typeMain = 'main'; |
|||
|
|||
export default () => { |
|||
return { |
|||
...Module, |
|||
|
|||
name: 'PageManager', |
|||
|
|||
storageKey: 'pages', |
|||
|
|||
Page, |
|||
|
|||
Pages, |
|||
|
|||
events: { |
|||
all: evAll, |
|||
select: evPageSelect, |
|||
selectBefore: evPageSelectBefore, |
|||
update: evPageUpdate, |
|||
add: evPageAdd, |
|||
addBefore: evPageAddBefore, |
|||
remove: evPageRemove, |
|||
removeBefore: evPageRemoveBefore, |
|||
}, |
|||
|
|||
/** |
|||
* Initialize module |
|||
* @param {Object} config Configurations |
|||
* @private |
|||
*/ |
|||
init(opts = {}) { |
|||
bindAll(this, '_onPageChange'); |
|||
const { em } = opts; |
|||
const cnf = { ...opts }; |
|||
this.config = cnf; |
|||
this.em = em; |
|||
const pages = new Pages([], cnf); |
|||
this.pages = pages; |
|||
this.all = pages; |
|||
const model = new Model({ _undo: true }); |
|||
this.model = model; |
|||
pages.on('add', (p, c, o) => em.trigger(evPageAdd, p, o)); |
|||
pages.on('remove', (p, c, o) => em.trigger(evPageRemove, p, o)); |
|||
pages.on('change', (p, c) => { |
|||
em.trigger(evPageUpdate, p, p.changedAttributes(), c); |
|||
}); |
|||
pages.on('reset', coll => coll.at(0) && this.select(coll.at(0))); |
|||
pages.on('all', this.__onChange, this); |
|||
model.on(chnSel, this._onPageChange); |
|||
|
|||
return this; |
|||
}, |
|||
|
|||
__onChange(event, page, coll, opts) { |
|||
const options = opts || coll; |
|||
this.em.trigger(evAll, { event, page, options }); |
|||
}, |
|||
|
|||
onLoad() { |
|||
const { pages } = this; |
|||
const opt = { silent: true }; |
|||
pages.add(this.config.pages || [], opt); |
|||
const mainPage = !pages.length ? this.add({ type: typeMain }, opt) : this.getMain(); |
|||
this.select(mainPage, opt); |
|||
}, |
|||
|
|||
_onPageChange(m, page, opts) { |
|||
const { em } = this; |
|||
const lm = em.get('LayerManager'); |
|||
const mainComp = page.getMainComponent(); |
|||
lm && mainComp && lm.setRoot(mainComp); |
|||
em.trigger(evPageSelect, page, m.previous('selected')); |
|||
this.__onChange(chnSel, page, opts); |
|||
}, |
|||
|
|||
postLoad() { |
|||
const { em, model } = this; |
|||
const um = em.get('UndoManager'); |
|||
um && um.add(model); |
|||
um && um.add(this.pages); |
|||
}, |
|||
|
|||
/** |
|||
* Add new page |
|||
* @param {Object} props Page properties |
|||
* @param {Object} [opts] Options |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const newPage = pageManager.add({ |
|||
* id: 'new-page-id', // without an explicit ID, a random one will be created
|
|||
* styles: `.my-class { color: red }`, // or a JSON of styles
|
|||
* component: '<div class="my-class">My element</div>', // or a JSON of components
|
|||
* }); |
|||
*/ |
|||
add(props, opts = {}) { |
|||
const { em } = this; |
|||
props.id = props.id || this._createId(); |
|||
const add = () => { |
|||
const page = this.pages.add(props, opts); |
|||
opts.select && this.select(page); |
|||
return page; |
|||
}; |
|||
!opts.silent && em.trigger(evPageAddBefore, props, add, opts); |
|||
return !opts.abort && add(); |
|||
}, |
|||
|
|||
/** |
|||
* Remove page |
|||
* @param {String|[Page]} page Page or page id |
|||
* @returns {[Page]} Removed Page |
|||
* @example |
|||
* const removedPage = pageManager.remove('page-id'); |
|||
* // or by passing the page
|
|||
* const somePage = pageManager.get('page-id'); |
|||
* pageManager.remove(somePage); |
|||
*/ |
|||
remove(page, opts = {}) { |
|||
const { em } = this; |
|||
const pg = isString(page) ? this.get(page) : page; |
|||
const rm = () => { |
|||
pg && this.pages.remove(pg, opts); |
|||
return pg; |
|||
}; |
|||
!opts.silent && em.trigger(evPageRemoveBefore, pg, rm, opts); |
|||
return !opts.abort && rm(); |
|||
}, |
|||
|
|||
/** |
|||
* Get page by id |
|||
* @param {String} id Page id |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const somePage = pageManager.get('page-id'); |
|||
*/ |
|||
get(id) { |
|||
return this.pages.filter(p => p.get('id') === id)[0]; |
|||
}, |
|||
|
|||
/** |
|||
* Get main page (the first one available) |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const mainPage = pageManager.getMain(); |
|||
*/ |
|||
getMain() { |
|||
const { pages } = this; |
|||
return pages.filter(p => p.get('type') === typeMain)[0] || pages.at(0); |
|||
}, |
|||
|
|||
/** |
|||
* Get all pages |
|||
* @returns {Array<[Page]>} |
|||
* @example |
|||
* const arrayOfPages = pageManager.getAll(); |
|||
*/ |
|||
getAll() { |
|||
return [...this.pages.models]; |
|||
}, |
|||
|
|||
/** |
|||
* Get wrapper components (aka body) from all pages and frames. |
|||
* @returns {Array<[Component]>} |
|||
* @example |
|||
* const wrappers = pageManager.getAllWrappers(); |
|||
* // Get all `image` components from the project
|
|||
* const allImages = wrappers.map(wrp => wrp.findType('image')).flat(); |
|||
*/ |
|||
getAllWrappers() { |
|||
const pages = this.getAll(); |
|||
return unique(flatten(pages.map(page => page.getAllFrames().map(frame => frame.getComponent())))); |
|||
}, |
|||
|
|||
getAllMap() { |
|||
return this.getAll().reduce((acc, i) => { |
|||
acc[i.get('id')] = i; |
|||
return acc; |
|||
}, {}); |
|||
}, |
|||
|
|||
/** |
|||
* Change the selected page. This will switch the page rendered in canvas |
|||
* @param {String|[Page]} page Page or page id |
|||
* @returns {this} |
|||
* @example |
|||
* pageManager.select('page-id'); |
|||
* // or by passing the page
|
|||
* const somePage = pageManager.get('page-id'); |
|||
* pageManager.select(somePage); |
|||
*/ |
|||
select(page, opts = {}) { |
|||
const pg = isString(page) ? this.get(page) : page; |
|||
if (pg) { |
|||
this.em.trigger(evPageSelectBefore, pg, opts); |
|||
this.model.set('selected', pg, opts); |
|||
} |
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Get the selected page |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const selectedPage = pageManager.getSelected(); |
|||
*/ |
|||
getSelected() { |
|||
return this.model.get('selected'); |
|||
}, |
|||
|
|||
destroy() { |
|||
this.pages.off().reset(); |
|||
this.model.stopListening(); |
|||
this.model.clear({ silent: true }); |
|||
['selected', 'config', 'em', 'pages', 'model'].map(i => (this[i] = 0)); |
|||
}, |
|||
|
|||
store() { |
|||
return this.getProjectData(); |
|||
}, |
|||
|
|||
load(data) { |
|||
return this.loadProjectData(data, { all: this.pages, reset: true }); |
|||
}, |
|||
|
|||
_createId() { |
|||
const pages = this.getAll(); |
|||
const len = pages.length + 16; |
|||
const pagesMap = this.getAllMap(); |
|||
let id; |
|||
|
|||
do { |
|||
id = createId(len); |
|||
} while (pagesMap[id]); |
|||
|
|||
return id; |
|||
}, |
|||
}; |
|||
}; |
|||
@ -0,0 +1,290 @@ |
|||
/** |
|||
* You can customize the initial state of the module from the editor initialization |
|||
* ```js
|
|||
* const editor = grapesjs.init({ |
|||
* .... |
|||
* pageManager: { |
|||
* pages: [ |
|||
* { |
|||
* id: 'page-id', |
|||
* styles: `.my-class { color: red }`, // or a JSON of styles
|
|||
* component: '<div class="my-class">My element</div>', // or a JSON of components
|
|||
* } |
|||
* ] |
|||
* }, |
|||
* }) |
|||
* ``` |
|||
* |
|||
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance |
|||
* |
|||
* ```js
|
|||
* const pageManager = editor.Pages; |
|||
* ``` |
|||
* |
|||
* ## Available Events |
|||
* * `page:add` - Added new page. The page is passed as an argument to the callback |
|||
* * `page:remove` - Page removed. The page is passed as an argument to the callback |
|||
* * `page:select` - New page selected. The newly selected page and the previous one, are passed as arguments to the callback |
|||
* * `page:update` - Page updated. The updated page and the object containing changes are passed as arguments to the callback |
|||
* * `page` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback |
|||
* |
|||
* ## Methods |
|||
* * [add](#add) |
|||
* * [get](#get) |
|||
* * [getAll](#getall) |
|||
* * [getAllWrappers](#getallwrappers) |
|||
* * [getMain](#getmain) |
|||
* * [remove](#remove) |
|||
* * [select](#select) |
|||
* * [getSelected](#getselected) |
|||
* |
|||
* [Page]: page.html |
|||
* [Component]: component.html |
|||
* |
|||
* @module Pages |
|||
*/ |
|||
|
|||
import { isString, bindAll, unique, flatten } from 'underscore'; |
|||
import { createId } from '../utils/mixins'; |
|||
import { Model, Module } from '../abstract'; |
|||
import { ItemManagerModule, ModuleConfig } from '../abstract/Module'; |
|||
import Pages from './model/Pages'; |
|||
import Page from './model/Page'; |
|||
import EditorModel from '../editor/model/Editor'; |
|||
|
|||
export const evAll = 'page'; |
|||
export const evPfx = `${evAll}:`; |
|||
export const evPageSelect = `${evPfx}select`; |
|||
export const evPageSelectBefore = `${evPageSelect}:before`; |
|||
export const evPageUpdate = `${evPfx}update`; |
|||
export const evPageAdd = `${evPfx}add`; |
|||
export const evPageAddBefore = `${evPageAdd}:before`; |
|||
export const evPageRemove = `${evPfx}remove`; |
|||
export const evPageRemoveBefore = `${evPageRemove}:before`; |
|||
const chnSel = 'change:selected'; |
|||
const typeMain = 'main'; |
|||
const events = { |
|||
all: evAll, |
|||
select: evPageSelect, |
|||
selectBefore: evPageSelectBefore, |
|||
update: evPageUpdate, |
|||
add: evPageAdd, |
|||
addBefore: evPageAddBefore, |
|||
remove: evPageRemove, |
|||
removeBefore: evPageRemoveBefore, |
|||
}; |
|||
|
|||
interface Config extends ModuleConfig { |
|||
pages?: string[]; |
|||
} |
|||
export default class PageManager extends ItemManagerModule<Config, Pages> { |
|||
storageKey = 'pages'; |
|||
|
|||
get pages() { |
|||
return this.all; |
|||
} |
|||
|
|||
model: Model; |
|||
/** |
|||
* Initialize module |
|||
* @param {Object} config Configurations |
|||
* @private |
|||
*/ |
|||
constructor(em: EditorModel) { |
|||
super(em, 'PageManager', new Pages([]), events); |
|||
bindAll(this, '_onPageChange'); |
|||
const model = new Model({ _undo: true } as any); |
|||
this.model = model; |
|||
this.pages.on('reset', (coll) => coll.at(0) && this.select(coll.at(0))); |
|||
this.pages.on('all', this.__onChange, this); |
|||
model.on(chnSel, this._onPageChange); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
__onChange(event: string, page: Page, coll: Pages, opts?: any) { |
|||
const options = opts || coll; |
|||
this.em.trigger(evAll, { event, page, options }); |
|||
} |
|||
|
|||
onLoad() { |
|||
const { pages } = this; |
|||
const opt = { silent: true }; |
|||
pages.add( |
|||
this.config.pages?.map( |
|||
(page) => new Page(page, { em: this.em, config: this.config }) |
|||
) || [], |
|||
opt |
|||
); |
|||
const mainPage = !pages.length |
|||
? this.add({ type: typeMain }, opt) |
|||
: this.getMain(); |
|||
mainPage && this.select(mainPage, opt); |
|||
} |
|||
|
|||
_onPageChange(m: any, page: Page, opts: any) { |
|||
const { em } = this; |
|||
const lm = em.get('LayerManager'); |
|||
const mainComp = page.getMainComponent(); |
|||
lm && mainComp && lm.setRoot(mainComp); |
|||
em.trigger(evPageSelect, page, m.previous('selected')); |
|||
this.__onChange(chnSel, page, opts); |
|||
} |
|||
|
|||
postLoad() { |
|||
const { em, model } = this; |
|||
const um = em.get('UndoManager'); |
|||
um && um.add(model); |
|||
um && um.add(this.pages); |
|||
} |
|||
|
|||
/** |
|||
* Add new page |
|||
* @param {Object} props Page properties |
|||
* @param {Object} [opts] Options |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const newPage = pageManager.add({ |
|||
* id: 'new-page-id', // without an explicit ID, a random one will be created
|
|||
* styles: `.my-class { color: red }`, // or a JSON of styles
|
|||
* component: '<div class="my-class">My element</div>', // or a JSON of components
|
|||
* }); |
|||
*/ |
|||
add( |
|||
props: any, //{ id?: string; styles: string; component: string },
|
|||
opts: any = {} |
|||
) { |
|||
const { em } = this; |
|||
props.id = props.id || this._createId(); |
|||
const add = () => { |
|||
const page = this.pages.add( |
|||
new Page(props, { em: this.em, config: this.config }), |
|||
opts |
|||
); |
|||
opts.select && this.select(page); |
|||
return page; |
|||
}; |
|||
!opts.silent && em.trigger(evPageAddBefore, props, add, opts); |
|||
return !opts.abort && add(); |
|||
} |
|||
|
|||
/** |
|||
* Remove page |
|||
* @param {String|[Page]} page Page or page id |
|||
* @returns {[Page]} Removed Page |
|||
* @example |
|||
* const removedPage = pageManager.remove('page-id'); |
|||
* // or by passing the page
|
|||
* const somePage = pageManager.get('page-id'); |
|||
* pageManager.remove(somePage); |
|||
*/ |
|||
remove(page: string | Page, opts: any = {}) { |
|||
const { em } = this; |
|||
const pg = isString(page) ? this.get(page) : page; |
|||
const rm = () => { |
|||
pg && this.pages.remove(pg, opts); |
|||
return pg; |
|||
}; |
|||
!opts.silent && em.trigger(evPageRemoveBefore, pg, rm, opts); |
|||
return !opts.abort && rm(); |
|||
} |
|||
|
|||
/** |
|||
* Get page by id |
|||
* @param {String} id Page id |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const somePage = pageManager.get('page-id'); |
|||
*/ |
|||
get(id: string) { |
|||
return this.pages.filter((p) => p.get(p.idAttribute) === id)[0]; |
|||
} |
|||
|
|||
/** |
|||
* Get main page (the first one available) |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const mainPage = pageManager.getMain(); |
|||
*/ |
|||
getMain() { |
|||
const { pages } = this; |
|||
return pages.filter((p) => p.get('type') === typeMain)[0] || pages.at(0); |
|||
} |
|||
|
|||
/** |
|||
* Get wrapper components (aka body) from all pages and frames. |
|||
* @returns {Array<[Component]>} |
|||
* @example |
|||
* const wrappers = pageManager.getAllWrappers(); |
|||
* // Get all `image` components from the project
|
|||
* const allImages = wrappers.map(wrp => wrp.findType('image')).flat(); |
|||
*/ |
|||
getAllWrappers() { |
|||
const pages = this.getAll(); |
|||
return unique( |
|||
flatten( |
|||
pages.map((page) => |
|||
page.getAllFrames().map((frame) => frame.getComponent()) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Change the selected page. This will switch the page rendered in canvas |
|||
* @param {String|[Page]} page Page or page id |
|||
* @returns {this} |
|||
* @example |
|||
* pageManager.select('page-id'); |
|||
* // or by passing the page
|
|||
* const somePage = pageManager.get('page-id'); |
|||
* pageManager.select(somePage); |
|||
*/ |
|||
select(page: string | Page, opts = {}) { |
|||
const pg = isString(page) ? this.get(page) : page; |
|||
if (pg) { |
|||
this.em.trigger(evPageSelectBefore, pg, opts); |
|||
this.model.set('selected', pg, opts); |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* Get the selected page |
|||
* @returns {[Page]} |
|||
* @example |
|||
* const selectedPage = pageManager.getSelected(); |
|||
*/ |
|||
getSelected() { |
|||
return this.model.get('selected'); |
|||
} |
|||
|
|||
destroy() { |
|||
this.pages.off().reset(); |
|||
this.model.stopListening(); |
|||
this.model.clear({ silent: true }); |
|||
//@ts-ignore
|
|||
['selected', 'model'].map((i) => (this[i] = 0)); |
|||
} |
|||
|
|||
store() { |
|||
return this.getProjectData(); |
|||
} |
|||
|
|||
load(data: any) { |
|||
return this.loadProjectData(data, { all: this.pages, reset: true }); |
|||
} |
|||
|
|||
_createId() { |
|||
const pages = this.getAll(); |
|||
const len = pages.length + 16; |
|||
const pagesMap = this.getAllMap(); |
|||
let id; |
|||
|
|||
do { |
|||
id = createId(len); |
|||
} while (pagesMap[id]); |
|||
|
|||
return id; |
|||
} |
|||
} |
|||
@ -1,26 +0,0 @@ |
|||
import { Collection } from '../../common'; |
|||
import Page from './Page'; |
|||
|
|||
export default class Pages extends Collection { |
|||
initialize(models, config = {}) { |
|||
this.config = config; |
|||
this.on('reset', this.onReset); |
|||
this.on('remove', this.onRemove); |
|||
} |
|||
|
|||
onReset(m, opts = {}) { |
|||
const prev = opts.previousModels || []; |
|||
prev.map(p => this.onRemove(p)); |
|||
} |
|||
|
|||
onRemove(removed) { |
|||
removed && removed.onRemove(); |
|||
} |
|||
|
|||
add(m, o = {}) { |
|||
const { config } = this; |
|||
return Collection.prototype.add.call(this, m, { ...o, config }); |
|||
} |
|||
} |
|||
|
|||
Pages.prototype.model = Page; |
|||
@ -0,0 +1,18 @@ |
|||
import { Collection } from '../../common'; |
|||
import Page from './Page'; |
|||
|
|||
export default class Pages extends Collection<Page> { |
|||
constructor(models: any) { |
|||
super(models); |
|||
this.on('reset', this.onReset); |
|||
this.on('remove', this.onRemove); |
|||
} |
|||
|
|||
onReset(m: Page, opts?: { previousModels?: Pages }) { |
|||
opts?.previousModels?.map((p) => this.onRemove(p)); |
|||
} |
|||
|
|||
onRemove(removed?: Page) { |
|||
removed?.onRemove(); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue