mirror of
https://github.com/nasa/openmct.git
synced 2025-06-18 15:18:12 +00:00
[Core] Allow listening for mutation
Allow listeners to register with a domain object's mutation capability to detect changes to that domain object. Allows other components to respond to these changes without resorting to polling on timestamp or similar. WTD-1329.
This commit is contained in:
@ -72,6 +72,13 @@ define(
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function MutationCapability(now, domainObject) {
|
function MutationCapability(now, domainObject) {
|
||||||
|
var listeners = [];
|
||||||
|
|
||||||
|
function notifyListeners(model) {
|
||||||
|
listeners.forEach(function (listener) {
|
||||||
|
listener(model);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function mutate(mutator, timestamp) {
|
function mutate(mutator, timestamp) {
|
||||||
// Get the object's model and clone it, so the
|
// Get the object's model and clone it, so the
|
||||||
@ -96,6 +103,7 @@ define(
|
|||||||
copyValues(model, result);
|
copyValues(model, result);
|
||||||
}
|
}
|
||||||
model.modified = useTimestamp ? timestamp : now();
|
model.modified = useTimestamp ? timestamp : now();
|
||||||
|
notifyListeners(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report the result of the mutation
|
// Report the result of the mutation
|
||||||
@ -107,6 +115,15 @@ define(
|
|||||||
return fastPromise(mutator(clone)).then(handleMutation);
|
return fastPromise(mutator(clone)).then(handleMutation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function listen(listener) {
|
||||||
|
listeners.push(listener);
|
||||||
|
return function unlisten() {
|
||||||
|
listeners = listeners.filter(function (l) {
|
||||||
|
return l !== listener;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* Alias of `mutate`, used to support useCapability.
|
* Alias of `mutate`, used to support useCapability.
|
||||||
@ -139,7 +156,16 @@ define(
|
|||||||
* @returns {Promise.<boolean>} a promise for the result
|
* @returns {Promise.<boolean>} a promise for the result
|
||||||
* of the mutation; true if changes were made.
|
* of the mutation; true if changes were made.
|
||||||
*/
|
*/
|
||||||
mutate: mutate
|
mutate: mutate,
|
||||||
|
/**
|
||||||
|
* Listen for mutations of this domain object's model.
|
||||||
|
* The provided listener will be invoked with the domain
|
||||||
|
* object's new model after any changes. To stop listening,
|
||||||
|
* invoke the function returned by this method.
|
||||||
|
* @param {Function} listener function to call on mutation
|
||||||
|
* @returns {Function} a function to stop listening
|
||||||
|
*/
|
||||||
|
listen: listen
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,26 @@ define(
|
|||||||
// Should have gotten a timestamp from 'now'
|
// Should have gotten a timestamp from 'now'
|
||||||
expect(testModel.modified).toEqual(42);
|
expect(testModel.modified).toEqual(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("notifies listeners of mutation", function () {
|
||||||
|
var mockCallback = jasmine.createSpy('callback');
|
||||||
|
mutation.listen(mockCallback);
|
||||||
|
mutation.invoke(function (m) {
|
||||||
|
m.number = 8;
|
||||||
|
});
|
||||||
|
expect(mockCallback).toHaveBeenCalled();
|
||||||
|
expect(mockCallback.mostRecentCall.args[0].number)
|
||||||
|
.toEqual(8);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows listeners to stop listening", function () {
|
||||||
|
var mockCallback = jasmine.createSpy('callback');
|
||||||
|
mutation.listen(mockCallback)(); // Unlisten immediately
|
||||||
|
mutation.invoke(function (m) {
|
||||||
|
m.number = 8;
|
||||||
|
});
|
||||||
|
expect(mockCallback).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
Reference in New Issue
Block a user