Skip to content

Commit

Permalink
Added onInvalid / onValid callbacks to Table, Selection, Ordering on …
Browse files Browse the repository at this point in the history
…the client
  • Loading branch information
Nathan Sobo authored and nathansobo committed Aug 4, 2010
1 parent c1450c5 commit e5e93d6
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 22 deletions.
5 changes: 4 additions & 1 deletion client/lib/monarch/model/local_field.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ _.constructor("Monarch.Model.LocalField", Monarch.Model.ConcreteField, {
clearValidationErrors: function() {
var wasInvalid = !this.fieldset.valid();
this.validationErrors = [];
if (this.record.onValidNode && wasInvalid && this.fieldset.valid()) this.record.onValidNode.publish();
if (wasInvalid && this.fieldset.valid()) {
if (this.record.onValidNode) this.record.onValidNode.publish();
this.record.table.recordMadeValid(this.record);
}
},

notModifiedAfter: function(date) {
Expand Down
1 change: 1 addition & 0 deletions client/lib/monarch/model/record.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ _.constructor("Monarch.Model.Record", {
assignValidationErrors: function(errorsByFieldName) {
this.local.assignValidationErrors(_.camelizeKeys(errorsByFieldName));
if (this.onInvalidNode) this.onInvalidNode.publish();
this.table.recordMadeInvalid(this);
},

allValidationErrors: function() {
Expand Down
11 changes: 4 additions & 7 deletions client/lib/monarch/model/relations/ordering.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,10 @@ _.constructor("Monarch.Model.Relations.Ordering", Monarch.Model.Relations.Relati
this.tupleUpdatedRemotely(record, changedFields);
}, this));

this.operandsSubscriptionBundle.add(this.operand.onDirty(function(record) {
this.recordMadeDirty(record);
}, this));

this.operandsSubscriptionBundle.add(this.operand.onClean(function(record) {
this.recordMadeClean(record);
}, this));
this.operandsSubscriptionBundle.add(this.operand.onDirty(this.hitch('recordMadeDirty')));
this.operandsSubscriptionBundle.add(this.operand.onClean(this.hitch('recordMadeClean')));
this.operandsSubscriptionBundle.add(this.operand.onInvalid(this.hitch('recordMadeInvalid')));
this.operandsSubscriptionBundle.add(this.operand.onValid(this.hitch('recordMadeValid')));
}
})

Expand Down
20 changes: 20 additions & 0 deletions client/lib/monarch/model/relations/relation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ _.constructor("Monarch.Model.Relations.Relation", {
this.onRemoteRemoveNode = new Monarch.SubscriptionNode();
this.onDirtyNode = new Monarch.SubscriptionNode();
this.onCleanNode = new Monarch.SubscriptionNode();
this.onInvalidNode = new Monarch.SubscriptionNode();
this.onValidNode = new Monarch.SubscriptionNode();
if (this.hasOperands) {
this.operandsSubscriptionBundle = new Monarch.SubscriptionBundle();
this.unsubscribeFromOperandsWhenThisNoLongerHasSubscribers();
Expand Down Expand Up @@ -194,6 +196,16 @@ _.constructor("Monarch.Model.Relations.Relation", {
return this.onCleanNode.subscribe(callback, context);
},

onInvalid: function(callback, context) {
this.subscribeToOperandsIfNeeded();
return this.onInvalidNode.subscribe(callback, context);
},

onValid: function(callback, context) {
this.subscribeToOperandsIfNeeded();
return this.onValidNode.subscribe(callback, context);
},

recordMadeDirty: function(record) {
this.onDirtyNode.publish(record);
},
Expand All @@ -202,6 +214,14 @@ _.constructor("Monarch.Model.Relations.Relation", {
this.onCleanNode.publish(record);
},

recordMadeInvalid: function(record) {
this.onInvalidNode.publish(record)
},

recordMadeValid: function(record) {
this.onValidNode.publish(record);
},

hasSubscribers: function() {
return !(this.onRemoteInsertNode.empty() && this.onRemoteRemoveNode.empty()
&& this.onRemoteUpdateNode.empty() && this.onDirtyNode.empty() && this.onCleanNode.empty());
Expand Down
8 changes: 8 additions & 0 deletions client/lib/monarch/model/relations/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ _.constructor("Monarch.Model.Relations.Selection", Monarch.Model.Relations.Relat
this.operandsSubscriptionBundle.add(this.operand.onClean(function(record) {
if (this.contains(record)) this.recordMadeClean(record);
}, this));

this.operandsSubscriptionBundle.add(this.operand.onInvalid(function(record) {
if (this.contains(record)) this.recordMadeInvalid(record);
}, this));

this.operandsSubscriptionBundle.add(this.operand.onValid(function(record) {
if (this.contains(record)) this.recordMadeValid(record);
}, this));
}
});

Expand Down
12 changes: 0 additions & 12 deletions client/spec/monarch/model/relations/difference_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,18 +198,6 @@ Screw.Unit(function(c) { with(c) {
});
});

scenario("for onClean callbacks", function() {
init(function() {
eventType = "onClean";
});
});

scenario("for onDirty callbacks", function() {
init(function() {
eventType = "onDirty";
});
});

it("subscribes to its #operand and memoizes tuples, then unsubscribes and clears the memoization, then resubscribes and rememoizes", function() {
var rightOperand = User.where({age: 28});
var difference = User.difference(rightOperand);
Expand Down
31 changes: 31 additions & 0 deletions client/spec/monarch/model/relations/selection_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,37 @@ Screw.Unit(function(c) { with(c) {
});
});
});

context("when a record is made invalid or valid in the selection's operand", function() {
var invalidCallback, validCallback;
before(function() {
invalidCallback = mockFunction('invalidCallback');
validCallback = mockFunction('validCallback');
selection.onInvalid(invalidCallback);
selection.onValid(validCallback);
});

context("when the record matches the selection's predicate", function() {
it("triggers onValid / onInvalid callbacks on the selection", function() {
var record = selection.first();
record.assignValidationErrors({age: ["too young!"]});
expect(invalidCallback).to(haveBeenCalled, withArgs(record));
record.clearValidationErrors();
expect(validCallback).to(haveBeenCalled, withArgs(record));
});
});

context("when the record does not match the selection's predicate", function() {
it("does not trigger onDirty / onClean callbacks on the selection", function() {
var record = User.fixture('mike');
expect(selection.contains(record)).to(beFalse);
record.assignValidationErrors({age: ["too young!"]});
expect(invalidCallback).toNot(haveBeenCalled);
record.clearValidationErrors();
expect(validCallback).toNot(haveBeenCalled);
});
});
});
});

describe("subscription propagation", function() {
Expand Down
24 changes: 22 additions & 2 deletions client/spec/monarch/model/relations/table_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,10 @@ Screw.Unit(function(c) { with(c) {
});
});

describe("dirty / clean callback triggering", function() {
describe("onDirty / onClean callback triggering", function() {
useLocalFixtures();

it("fires dirty / clean callbacks when a record in the table becomes dirty or clean", function() {
it("fires onDirty / onClean callbacks when a record in the table becomes dirty or clean", function() {
var dirtyCallback = mockFunction('dirtyCallback');
var cleanCallback = mockFunction('cleanCallback');

Expand All @@ -224,6 +224,26 @@ Screw.Unit(function(c) { with(c) {
});
});

describe("onInvalid / onValid callback triggering", function() {
useLocalFixtures();

it("fires onInvalid / onValid callbacks when a record in the table becomes invalid or valid again", function() {
var invalidCallback = mockFunction('invalidCallback');
var validCallback = mockFunction('validCallback');

User.table.onInvalid(invalidCallback);
User.table.onValid(validCallback);

var user = User.fixture('jan');
user.assignValidationErrors({fullName: ["some error"]});

expect(invalidCallback).to(haveBeenCalled, withArgs(user));

user.clearValidationErrors();
expect(validCallback).to(haveBeenCalled, withArgs(user));
});
});

describe("#pauseEvents and #resumeEvents", function() {
specify("#pauseEvents delays #onRemoteInsert, #onRemoteRemove, and #onRemoteUpdate triggers until #resumeEvents is called. Then delayed events are flushed and future events are no longer delayed", function() {
var insertCallback = mockFunction("insert callback");
Expand Down

0 comments on commit e5e93d6

Please sign in to comment.