Skip to content

Commit

Permalink
frint-data: drop method watchers.
Browse files Browse the repository at this point in the history
  • Loading branch information
fahad19 committed Sep 21, 2017
1 parent 8860728 commit 186f3f1
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 251 deletions.
26 changes: 1 addition & 25 deletions packages/frint-data/src/createCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import BaseCollection from './base/Collection';
import Event from './base/Event';
import applyEventsMixin from './mixins/events';
import bubbleUpEvent from './utils/bubbleUpEvent';
import wrapCustomMethod from './utils/wrapCustomMethod';
import makeMethodReactive from './utils/makeMethodReactive';
import extractMethods from './utils/extractMethods';

Expand Down Expand Up @@ -66,30 +65,21 @@ export default function createCollection(options = {}) {
throw new CollectionError('Model instance is not of the one Collection is expecting');
}

this.trigger('method:call', new Event({ path: ['push'] }));

const result = models.push(model);
const index = result - 1;
this.trigger('change', new Event({ path: [index] }));
this.trigger('method:change', new Event({ path: ['push'] }));

const changeWatcher = bubbleUp(model, 'change');
const methodCallWatcher = bubbleUp(model, 'method:call');
const methodChangeWatcher = bubbleUp(model, 'method:change');

// @TODO: these listeners should be cleared?
model.on('destroy', () => {
this.remove(model);
changeWatcher();
methodCallWatcher();
methodChangeWatcher();
});

model.on('remove', () => {
this.trigger('change');
changeWatcher();
methodCallWatcher();
methodChangeWatcher();
});

return result;
Expand Down Expand Up @@ -133,23 +123,19 @@ export default function createCollection(options = {}) {
});

this.pop = function () {
this.trigger('method:call', new Event({ path: ['pop'] }));
const model = models.pop();

this.trigger('change');
this.trigger('method:change', new Event({ path: ['pop'] }));

model.trigger('remove');

return model;
};

this.shift = function () {
this.trigger('method:call', new Event({ path: ['shift'] }));
const model = models.shift();

this.trigger('change');
this.trigger('method:change', new Event({ path: ['shift'] }));

model.trigger('remove');

Expand All @@ -165,24 +151,18 @@ export default function createCollection(options = {}) {
throw new CollectionError('Model instance is not of the one Collection is expecting');
}

this.trigger('method:call', new Event({ path: ['unshift'] }));
const result = models.unshift(model);

this.trigger('change', new Event({ path: [0] }));
this.trigger('method:change', new Event({ path: ['unshift'] }));

const changeWatcher = bubbleUp(model, 'change');
const methodCallWatcher = bubbleUp(model, 'method:call');
const methodChangeWatcher = bubbleUp(model, 'method:change');

// @TODO: how are these listeners cleared later?
model.on('destroy', () => {
this.remove(model);
this.trigger('change');

changeWatcher();
methodCallWatcher();
methodChangeWatcher();
});

return result;
Expand All @@ -201,21 +181,17 @@ export default function createCollection(options = {}) {
return;
}

this.trigger('method:call', new Event({ path: ['removeFrom'] }));
models.splice(index, 1);
model.destroy();
this.trigger('change');
this.trigger('method:change', new Event({ path: ['removeFrom'] }));
};

this.destroy = function () {
this.trigger('method:call', new Event({ path: ['destroy'] }));
models.forEach(function (model) {
model.destroy();
});

this.trigger('destroy');
this.trigger('method:change', new Event({ path: ['destroy'] }));
this.off();
};

Expand All @@ -232,7 +208,7 @@ export default function createCollection(options = {}) {
throw new MethodError(`conflicting method name: ${methodName}`);
}

this[methodName] = wrapCustomMethod(this, methodName, methodFunc);
this[methodName] = methodFunc.bind(this);
});

// initialize
Expand Down
9 changes: 1 addition & 8 deletions packages/frint-data/src/createModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import BaseModel from './base/Model';
import Event from './base/Event';
import applyEventsMixin from './mixins/events';
import bubbleUpEvent from './utils/bubbleUpEvent';
import wrapCustomMethod from './utils/wrapCustomMethod';
import makeMethodReactive from './utils/makeMethodReactive';
import extractMethods from './utils/extractMethods';

Expand Down Expand Up @@ -68,9 +67,7 @@ export default function createModel(options = {}) {
// destroy()
Object.defineProperty(this, 'destroy', {
value: function () {
this.trigger('method:call', new Event({ path: ['destroy'] }));
this.trigger('destroy');
this.trigger('method:change', new Event({ path: ['destroy'] }));
this.off();

_.each(attributes, function (v) {
Expand Down Expand Up @@ -155,8 +152,6 @@ export default function createModel(options = {}) {
// watch children
if (isModel(value) || isCollection(value)) {
const changeWatcher = bubbleUpEvent(self, value, 'change', [attributeName]);
const methodCallWatcher = bubbleUpEvent(self, value, 'method:call', [attributeName]);
const methodChangeWatcher = bubbleUpEvent(self, value, 'method:change', [attributeName]);

// @TODO: listener should be cleared later?
value.on('destroy', function () {
Expand All @@ -165,8 +160,6 @@ export default function createModel(options = {}) {
}));

changeWatcher();
methodCallWatcher();
methodChangeWatcher();
});
}
});
Expand All @@ -180,7 +173,7 @@ export default function createModel(options = {}) {
throw new MethodError(`conflicting method name: ${methodName}`);
}

this[methodName] = wrapCustomMethod(this, methodName, func);
this[methodName] = func.bind(this);
});

// initializers
Expand Down
176 changes: 0 additions & 176 deletions packages/frint-data/src/createModel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -632,182 +632,6 @@ describe('frint-data › createModel', function () {
}));
});

it('emits `method:change` event for self', function () {
const Book = createModel({
schema: {
title: Types.string.isRequired,
description: Types.string.isRequired,
},
getTitle() {
return this.title;
},
setTitle(title) {
this.title = title;
},
getDescription() {
return this.description;
},
setDescription(description) {
this.description = description;
},
setTitleAndDescription(title, description) {
this.title = title;
this.description = description;
},
});

const book = new Book({
title: 'Book Title',
description: 'hello...'
});

let count = 0;
const watcher = book.on('method:change', function () {
count += 1;
});

book.getTitle();
book.getTitle();
expect(count).to.eql(0);

book.setTitle('Book Title [updated]'); // +1
expect(count).to.eql(1);

book.getDescription();
book.getDescription();
expect(count).to.eql(1);

book.setDescription('blah...'); // +1
expect(count).to.eql(2);

book.setTitleAndDescription('Title here', 'description here'); // +1
expect(count).to.eql(3);

watcher();
});

it('emits `method:change` event for child-model', function () {
const Address = createModel({
schema: {
street: Types.string,
city: Types.string,
},
setStreet(street) {
this.street = street;
},
});

const Person = createModel({
schema: {
name: Types.string.isRequired,
address: Types.model.of(Address),
},
});

const person = new Person({
name: 'Vernon Dursley',
address: {
street: 'Privet Drive',
city: 'Surrey'
}
});

let count = 0;
const watcher = person.on('method:change', function (event) {
count += 1;

expect(isEvent(event)).to.eql(true);
expect(event.path).to.eql(['address', 'setStreet']);
expect(person.address.street).to.eql('4 Privet Drive');
});

person.address.setStreet('4 Privet Drive');
expect(count).to.eql(1);
watcher();
});

it('emits `method:change` event for child-collection', function () {
const Book = createModel({
schema: {
title: Types.string.isRequired,
},
setTitle(title) {
this.title = title;
},
});

const Books = createCollection({
model: Book,
add(title) {
return this.push(new Book({
title
}));
}
});

const Author = createModel({
schema: {
name: Types.string.isRequired,
books: Types.collection.of(Books),
},
});

const author = new Author({
name: 'Rita Skeeter',
books: [
{ title: 'The Life and Lies of Dumbledore' }
]
});

let watcher;
let count = 0;

// first change
watcher = author.on('method:change', function (event) {
count += 1;

expect(isEvent(event)).to.eql(true);
expect(event.path).to.eql(['books', 0, 'setTitle']);
expect(author.books.at(0).title).to.eql('The Life and Lies of Albus Dumbledore');
});

author.books.at(0).setTitle('The Life and Lies of Albus Dumbledore');
watcher();
expect(count).to.eql(1);

// second change
count = 0;
watcher = author.on('method:change', function (event) {
count += 1;

expect(isEvent(event)).to.eql(true);
expect(event.path).to.eql(['books', 'push']);
expect(author.books.at(1).title).to.eql(`Dumbledore's Army`);
});

author.books.push(new Book({
title: `Dumbledore's Army`
}));
watcher();

// third change
count = 0;
const events = [];
watcher = author.on('method:change', function (event) {
count += 1;
events.push(event);

expect(isEvent(event)).to.eql(true);
expect(author.books.at(2).title).to.eql('A new book name');
});

author.books.add('A new book name');
watcher();

expect(count).to.eql(2);
expect(events[1].path).to.eql(['books', 'add']);
});

it('applies initializers', function () {
function initializer(model) {
model.setName('Updated by initializer');
Expand Down
42 changes: 0 additions & 42 deletions packages/frint-data/src/utils/wrapCustomMethod.js

This file was deleted.

0 comments on commit 186f3f1

Please sign in to comment.