New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

watch string comparator, cache spec, refactor configure #27

Closed
wants to merge 14 commits into
base: master
from

Conversation

Projects
None yet
5 participants
@aaronmccall

aaronmccall commented Dec 5, 2014

closes #15

@lukekarrys

This comment has been minimized.

Show comment
Hide comment
@lukekarrys

lukekarrys Dec 5, 2014

Contributor

+1 on adding the comparator to the watch list if its a string.

I'm confused on what is the difference between the new spec.watch and spec.watched?

Contributor

lukekarrys commented Dec 5, 2014

+1 on adding the comparator to the watch list if its a string.

I'm confused on what is the difference between the new spec.watch and spec.watched?

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 5, 2014

My bad! I missed the spec.watched. I'll amend the PR.

aaronmccall commented Dec 5, 2014

My bad! I missed the spec.watched. I'll amend the PR.

@aaronmccall aaronmccall changed the title from add string comparator and declared watches to _watched to add string comparator to _watched Dec 5, 2014

@lukekarrys

This comment has been minimized.

Show comment
Hide comment
@lukekarrys

lukekarrys Dec 5, 2014

Contributor

+1 @aaronmccall. Maybe squash the commits to include just the first relevant one?

Contributor

lukekarrys commented Dec 5, 2014

+1 @aaronmccall. Maybe squash the commits to include just the first relevant one?

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall commented Dec 5, 2014

Squashed!

@legastero

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 5, 2014

Good call, @legastero! On it.

aaronmccall commented Dec 5, 2014

Good call, @legastero! On it.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 5, 2014

Ok, @legastero and @lukekarrys, the problem as I see it is that we can't reset _watched back to the original spec.watched because we only have it in its unchanged state in the constructor at L13. This means that either we need a way to keep a reference to an unmodified version of the original spec.watched to re-initialize _watched with, or we need to allow configure (see L75) to re-initialize it, or both.

aaronmccall commented Dec 5, 2014

Ok, @legastero and @lukekarrys, the problem as I see it is that we can't reset _watched back to the original spec.watched because we only have it in its unchanged state in the constructor at L13. This means that either we need a way to keep a reference to an unmodified version of the original spec.watched to re-initialize _watched with, or we need to allow configure (see L75) to re-initialize it, or both.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 5, 2014

What about doing something like this?

diff --git a/ampersand-subcollection.js b/ampersand-subcollection.js
index 4fb13b5..ec6d0be 100644
--- a/ampersand-subcollection.js
+++ b/ampersand-subcollection.js
@@ -7,10 +7,10 @@ var slice = Array.prototype.slice;


 function SubCollection(collection, spec) {
-    spec || (spec = {});
+    this._spec = (spec || (spec = {}));
     this.collection = collection;
     this._reset();
-    this._watched = spec.watched || [];
+    this._watch(spec.watched);
     this._parseFilters(spec);
     this._runFilters();
     this.listenTo(this.collection, 'all', this._onCollectionEvent);
@@ -73,7 +73,12 @@ _.extend(SubCollection.prototype, Events, underscoreMixins, {
     //   limit: 20
     // }
     configure: function (opts, clear) {
-        if (clear) this._resetFilters();
+
+        if (clear) {
+            this._spec = {};
+            this._resetFilters();
+        }
+        this._watch(opts.watched);
         this._parseFilters(opts);
         this._runFilters();
     },
@@ -107,6 +112,7 @@ _.extend(SubCollection.prototype, Events, underscoreMixins, {
     _resetFilters: function () {
         this._filters = [];
         this._watched = [];
+        this._watch(this._spec.watched);
         this.limit = undefined;
         this.offset = undefined;
     },

aaronmccall commented Dec 5, 2014

What about doing something like this?

diff --git a/ampersand-subcollection.js b/ampersand-subcollection.js
index 4fb13b5..ec6d0be 100644
--- a/ampersand-subcollection.js
+++ b/ampersand-subcollection.js
@@ -7,10 +7,10 @@ var slice = Array.prototype.slice;


 function SubCollection(collection, spec) {
-    spec || (spec = {});
+    this._spec = (spec || (spec = {}));
     this.collection = collection;
     this._reset();
-    this._watched = spec.watched || [];
+    this._watch(spec.watched);
     this._parseFilters(spec);
     this._runFilters();
     this.listenTo(this.collection, 'all', this._onCollectionEvent);
@@ -73,7 +73,12 @@ _.extend(SubCollection.prototype, Events, underscoreMixins, {
     //   limit: 20
     // }
     configure: function (opts, clear) {
-        if (clear) this._resetFilters();
+
+        if (clear) {
+            this._spec = {};
+            this._resetFilters();
+        }
+        this._watch(opts.watched);
         this._parseFilters(opts);
         this._runFilters();
     },
@@ -107,6 +112,7 @@ _.extend(SubCollection.prototype, Events, underscoreMixins, {
     _resetFilters: function () {
         this._filters = [];
         this._watched = [];
+        this._watch(this._spec.watched);
         this.limit = undefined;
         this.offset = undefined;
     },
@lukekarrys

This comment has been minimized.

Show comment
Hide comment
@lukekarrys

lukekarrys Dec 5, 2014

Contributor

@aaronmccall I think that looks good. Now that we're expanding the scope of this issue, we should probably go ahead and test all this behavior as well.

Contributor

lukekarrys commented Dec 5, 2014

@aaronmccall I think that looks good. Now that we're expanding the scope of this issue, we should probably go ahead and test all this behavior as well.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 5, 2014

Agreed. I'll start writing tests.

aaronmccall commented Dec 5, 2014

Agreed. I'll start writing tests.

@aaronmccall aaronmccall changed the title from add string comparator to _watched to watch string comparator, cache spec, refactor configure Dec 8, 2014

@HenrikJoreteg

This comment has been minimized.

Show comment
Hide comment
@HenrikJoreteg

HenrikJoreteg Dec 8, 2014

Member

Seems unexpected that anything, such as the _watched list would be maintained during a reset: https://github.com/AmpersandJS/ampersand-subcollection/pull/27/files#diff-ee4701d13a7c5fb628bd1061d96bb1d1R121

Then there's no way to truly reset and reconfigure.

Also, keeping and then extending original spec: https://github.com/AmpersandJS/ampersand-subcollection/pull/27/files#diff-ee4701d13a7c5fb628bd1061d96bb1d1R84 seems troublesome if you're really wanting to reconfigure things over time.

Member

HenrikJoreteg commented Dec 8, 2014

Seems unexpected that anything, such as the _watched list would be maintained during a reset: https://github.com/AmpersandJS/ampersand-subcollection/pull/27/files#diff-ee4701d13a7c5fb628bd1061d96bb1d1R121

Then there's no way to truly reset and reconfigure.

Also, keeping and then extending original spec: https://github.com/AmpersandJS/ampersand-subcollection/pull/27/files#diff-ee4701d13a7c5fb628bd1061d96bb1d1R84 seems troublesome if you're really wanting to reconfigure things over time.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 8, 2014

@HenrikJoreteg,

  • Regarding your first point: The _watched list is only maintained through _resetFilters, not through configure(config, true). I would be surprised if resetting filters reset anything else—non-filter watches, for instance. What is happening with the proposed change is that the where keys are being removed from _watched but explicitly configured spec.watched and comparator watches are maintained.
  • Regarding the second, I believe you may have missed the reinitialization of this._spec at https://github.com/AmpersandJS/ampersand-subcollection/pull/27/files#diff-ee4701d13a7c5fb628bd1061d96bb1d1R80

aaronmccall commented Dec 8, 2014

@HenrikJoreteg,

  • Regarding your first point: The _watched list is only maintained through _resetFilters, not through configure(config, true). I would be surprised if resetting filters reset anything else—non-filter watches, for instance. What is happening with the proposed change is that the where keys are being removed from _watched but explicitly configured spec.watched and comparator watches are maintained.
  • Regarding the second, I believe you may have missed the reinitialization of this._spec at https://github.com/AmpersandJS/ampersand-subcollection/pull/27/files#diff-ee4701d13a7c5fb628bd1061d96bb1d1R80
@HenrikJoreteg

This comment has been minimized.

Show comment
Hide comment
@HenrikJoreteg

HenrikJoreteg Dec 8, 2014

Member

I did miss the re-init of this._spec but I don't see in this code how you'd ever reset all the things?

Member

HenrikJoreteg commented Dec 8, 2014

I did miss the re-init of this._spec but I don't see in this code how you'd ever reset all the things?

@HenrikJoreteg

This comment has been minimized.

Show comment
Hide comment
@HenrikJoreteg

HenrikJoreteg Dec 8, 2014

Member

Also, i think perhaps clearFilters is causing some confusion. Both where and limit and offset are really just "filters" for all practical purposes.

Member

HenrikJoreteg commented Dec 8, 2014

Also, i think perhaps clearFilters is causing some confusion. Both where and limit and offset are really just "filters" for all practical purposes.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 8, 2014

The steps in the proposed configure and _resetFilters changes ensure that configure(config, true) actually resets everything where now it doesn't since in the current version, we have the issue mentioned in #11, where the only way to reset the comparator is to manually remove it.

In the proposed changes, given that _spec is reset to an empty object (L80), comparator is being deleted (L81), _resetFilters is being run (L82)—removing all _filters and limit and offset, and rebuilding _spec from the passed in opts (L84), everything should be reset, shouldn't it?

It also ensures that you don't accidentally remove watches that should be maintained when _resetFilters is called.

aaronmccall commented Dec 8, 2014

The steps in the proposed configure and _resetFilters changes ensure that configure(config, true) actually resets everything where now it doesn't since in the current version, we have the issue mentioned in #11, where the only way to reset the comparator is to manually remove it.

In the proposed changes, given that _spec is reset to an empty object (L80), comparator is being deleted (L81), _resetFilters is being run (L82)—removing all _filters and limit and offset, and rebuilding _spec from the passed in opts (L84), everything should be reset, shouldn't it?

It also ensures that you don't accidentally remove watches that should be maintained when _resetFilters is called.

@HenrikJoreteg

This comment has been minimized.

Show comment
Hide comment
@HenrikJoreteg

HenrikJoreteg Dec 8, 2014

Member

Yeah, using configure({}, true) clears things, but the semantics of the rest of it is what seems like it could be better.

I think we need a method that fully resets everything and I don't think the only way to trigger this behavior should be by passing true to configure.

clearFilters was supposed to be that, but the name doesn't match that intent.

I wonder if we shouldn't do this:

  • clearFilters - removes any of the previously registered filter functions and where rules (since those are just declarative filters). It also removes relevant things from watched list. Basically, reset everything other than comparator.
  • change _reset to reset and have it do what it says on the box: "reset all the things" including comparator.
  • I don't think this code belongs in a reset.
  • I think this code should just happen as part of the reset.

Also, rather than just treating it as a generic watched i think the case of the string-based comparator, might make more sense to just handle separately by including in the list here: https://github.com/aaronmccall/ampersand-subcollection/blob/master/ampersand-subcollection.js#L220 then we don't have to maintain it as a "special" watched property.

Member

HenrikJoreteg commented Dec 8, 2014

Yeah, using configure({}, true) clears things, but the semantics of the rest of it is what seems like it could be better.

I think we need a method that fully resets everything and I don't think the only way to trigger this behavior should be by passing true to configure.

clearFilters was supposed to be that, but the name doesn't match that intent.

I wonder if we shouldn't do this:

  • clearFilters - removes any of the previously registered filter functions and where rules (since those are just declarative filters). It also removes relevant things from watched list. Basically, reset everything other than comparator.
  • change _reset to reset and have it do what it says on the box: "reset all the things" including comparator.
  • I don't think this code belongs in a reset.
  • I think this code should just happen as part of the reset.

Also, rather than just treating it as a generic watched i think the case of the string-based comparator, might make more sense to just handle separately by including in the list here: https://github.com/aaronmccall/ampersand-subcollection/blob/master/ampersand-subcollection.js#L220 then we don't have to maintain it as a "special" watched property.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 8, 2014

Now we're getting somewhere! I'll work through this and see where it takes us!

aaronmccall commented Dec 8, 2014

Now we're getting somewhere! I'll work through this and see where it takes us!

@HenrikJoreteg

This comment has been minimized.

Show comment
Hide comment
@HenrikJoreteg

HenrikJoreteg Dec 8, 2014

Member

yeah, sorry my first attempts at articulating my feedback were terrible :) Thanks for your patience.

Member

HenrikJoreteg commented Dec 8, 2014

yeah, sorry my first attempts at articulating my feedback were terrible :) Thanks for your patience.

@@ -144,9 +151,6 @@ _.extend(SubCollection.prototype, Events, underscoreMixins, {
if (spec.filters) {
spec.filters.forEach(this._addFilter, this);
}
if (spec.comparator) {

This comment has been minimized.

@HenrikJoreteg

HenrikJoreteg Dec 9, 2014

Member

Any particular reason you removed this from here? now it's duplicated in the constructor and configure instead. The idea for parseFilters is split out so you can can either create or call configure with the same object structure and everything works.

@HenrikJoreteg

HenrikJoreteg Dec 9, 2014

Member

Any particular reason you removed this from here? now it's duplicated in the constructor and configure instead. The idea for parseFilters is split out so you can can either create or call configure with the same object structure and everything works.

This comment has been minimized.

@aaronmccall

aaronmccall Dec 9, 2014

Maybe it should be called _parseSpec and initialize _watched, _filters, and comparator?

@aaronmccall

aaronmccall Dec 9, 2014

Maybe it should be called _parseSpec and initialize _watched, _filters, and comparator?

This comment has been minimized.

@HenrikJoreteg

HenrikJoreteg Dec 9, 2014

Member

makes sense to me

@HenrikJoreteg

HenrikJoreteg Dec 9, 2014

Member

makes sense to me

@HenrikJoreteg

This comment has been minimized.

Show comment
Hide comment
@HenrikJoreteg

HenrikJoreteg Dec 9, 2014

Member

Will also need documentation update to match these changes.

Member

HenrikJoreteg commented Dec 9, 2014

Will also need documentation update to match these changes.

@aaronmccall

This comment has been minimized.

Show comment
Hide comment
@aaronmccall

aaronmccall Dec 9, 2014

@HenrikJoreteg, if we're good to go with the code changes, I can update docs to match.

aaronmccall commented Dec 9, 2014

@HenrikJoreteg, if we're good to go with the code changes, I can update docs to match.

Show outdated Hide outdated test/main.js
make sure 'reset' fires events.
use '_resetFilters' in 'configure' instead of 'reset'.
add tests for 'reset'
add tests for 'clearFilters'
removing 'comparator' should set it back to parent's 'comparator'
includes #27

@HenrikJoreteg HenrikJoreteg referenced this pull request Dec 9, 2014

Merged

Refactor configure #28

Aaron McCall added some commits Dec 11, 2014

Aaron McCall
move comparator reset to _resetFilters
- put it behind a param flag
- corrects bug with configure({}, true) not resetting comparator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment