angular-primus
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -1,2 +0,2 @@ | ||
/*! Angular primus v1.0.0 | (c) 2013 Greg Bergé | License MIT */ | ||
/*! Angular primus v1.0.1 | (c) 2013 Greg Bergé | License MIT */ | ||
@@ -26,3 +26,3 @@ angular | ||
* Listen on events of a given type. | ||
* Calls the listener inside a $rootScope.$apply. | ||
* Calls the listener inside in Angular context ($evalAsync) | ||
* | ||
@@ -35,8 +35,8 @@ * @param {String} event | ||
primus.$on = function $on(event, listener) { | ||
// Wrap primus event with $rootScope.$apply. | ||
primus.on(event, applyListener); | ||
// run the listener in Angular context | ||
primus.on(event, listenerInAngularContext); | ||
function applyListener() { | ||
function listenerInAngularContext() { | ||
var args = arguments; | ||
$rootScope.$apply(function () { | ||
$rootScope.$evalAsync(function () { | ||
listener.apply(null, args); | ||
@@ -48,3 +48,3 @@ }); | ||
return function $off() { | ||
primus.removeListener(event, applyListener); | ||
primus.removeListener(event, listenerInAngularContext); | ||
}; | ||
@@ -55,3 +55,3 @@ }; | ||
* Listen on events of a given type, with a filtering pattern. | ||
* If the pattern matches, calls the listener inside a $rootScope.$apply. | ||
* If the pattern matches, calls the listener in Angular context ($evalAsync) | ||
* | ||
@@ -67,4 +67,2 @@ * @param {String} event | ||
primus.$filteredOn = function $filteredOn(event, matchPattern, listener) { | ||
// Wrap primus event with $rootScope.$apply. | ||
primus.on(event, applyListener); | ||
@@ -79,7 +77,11 @@ var checkMatch; | ||
function applyListener() { | ||
// run the listener in Angular context | ||
primus.on(event, filteredListenerInAngularContext); | ||
function filteredListenerInAngularContext() { | ||
var args = arguments; | ||
var isMatching = checkMatch(args[0]); | ||
if (! isMatching) return; | ||
$rootScope.$apply(function () { | ||
$rootScope.$evalAsync(function () { | ||
listener.apply(null, args); | ||
@@ -91,3 +93,3 @@ }); | ||
return function $off() { | ||
primus.removeListener(event, applyListener); | ||
primus.removeListener(event, filteredListenerInAngularContext); | ||
}; | ||
@@ -94,0 +96,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
/*! Angular primus v1.0.0 | (c) 2013 Greg Bergé | License MIT */ | ||
function primusProvider(){function a(a,c){var d=new Primus(this.endpoint,this.options),e={};return d.$on=function(b,c){function e(){var b=arguments;a.$apply(function(){c.apply(null,b)})}return d.on(b,e),function(){d.removeListener(b,e)}},d.$filteredOn=function(b,c,e){function f(){var b=arguments,c=g(b[0]);c&&a.$apply(function(){e.apply(null,b)})}d.on(b,f);var g;if(_.isFunction(c))g=c;else{if(!_.isObject(c))throw new Error("angular-primus $filteredOn() : matchPattern must be a function or an object !");g=_.matches(c)}return function(){d.removeListener(b,f)}},d.$resource=function(f,g){if(g="undefined"==typeof g?b.multiplex:g,e[f])return e[f].promise;e[f]=c.defer();var h=d.resource(f,g);return h.once("ready",function(){e[f].resolve(h),a.$apply()}),e[f].promise},d}var b=this;this.$get=["$rootScope","$q",a],this.setOptions=function(a){return this.options=a,this},this.setEndpoint=function(a){return this.endpoint=a,this},this.setDefaultMultiplex=function(a){return this.multiplex=a,this}}angular.module("primus",[]).provider("primus",primusProvider); | ||
/*! Angular primus v1.0.1 | (c) 2013 Greg Bergé | License MIT */ | ||
function primusProvider(){function a(a,c){var d=new Primus(this.endpoint,this.options),e={};return d.$on=function(b,c){function e(){var b=arguments;a.$evalAsync(function(){c.apply(null,b)})}return d.on(b,e),function(){d.removeListener(b,e)}},d.$filteredOn=function(b,c,e){function f(){var b=arguments,c=g(b[0]);c&&a.$evalAsync(function(){e.apply(null,b)})}var g;if(_.isFunction(c))g=c;else{if(!_.isObject(c))throw new Error("angular-primus $filteredOn() : matchPattern must be a function or an object !");g=_.matches(c)}return d.on(b,f),function(){d.removeListener(b,f)}},d.$resource=function(f,g){if(g="undefined"==typeof g?b.multiplex:g,e[f])return e[f].promise;e[f]=c.defer();var h=d.resource(f,g);return h.once("ready",function(){e[f].resolve(h),a.$apply()}),e[f].promise},d}var b=this;this.$get=["$rootScope","$q",a],this.setOptions=function(a){return this.options=a,this},this.setEndpoint=function(a){return this.endpoint=a,this},this.setDefaultMultiplex=function(a){return this.multiplex=a,this}}angular.module("primus",[]).provider("primus",primusProvider); | ||
//# sourceMappingURL=angular-primus.min.map |
{ | ||
"name": "angular-primus", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"homepage": "https://github.com/neoziro/angular-primus", | ||
@@ -5,0 +5,0 @@ "authors": [ |
{ | ||
"name": "angular-primus", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Primus provider for Angular.", | ||
@@ -5,0 +5,0 @@ "main": "angular-primus.js", |
@@ -50,2 +50,8 @@ # angular-primus [![Build Status](https://travis-ci.org/neoziro/angular-primus.svg?branch=master)](https://travis-ci.org/neoziro/angular-primus) | ||
// Listen custom event with a filter (more details below) | ||
// ex. server broadcasting a user account update : | ||
primus.$on('account:update', {userId: 23}, function (account) { | ||
_.merge($scope.account, account); | ||
}); | ||
// Send data using primus-emitter. | ||
@@ -62,4 +68,18 @@ primus.send('customEvent', { foo: 'bar' }); | ||
### about $on and $filteredOn | ||
`$filteredOn` takes as filter either : | ||
* an object, whom keys will be deep-matched for correspondance with the 1st param of received data, using [lodash matches(...)](https://lodash.com/docs#matches). Example of a deep matching : | ||
```javascript | ||
primus.$on('node:update', {content: {id: 23, type: 'image'}}, …) | ||
``` | ||
* a function, taking the received data as arguments and returning true/false = match/don't match | ||
Both `$on` and `$filteredOn` will call the listener **in Angular context**, in an optimized way via [$evalAsync](http://www.bennadel.com/blog/2751-scope-applyasync-vs-scope-evalasync-in-angularjs-1-3.htm). So if you have several listeners on the same event, they will all get executed in the same $digest phase. | ||
`$filteredOn` will not trigger any apply if the received data doesn't match the given filter. This is desirable if your Angular app is heavy. | ||
## License | ||
MIT |
@@ -104,7 +104,7 @@ var expect = chai.expect; | ||
it('should wrap method in $rootScope.$apply', function () { | ||
it('should call the listener in Angular context', function () { | ||
var watchSpy = sinon.spy(); | ||
$rootScope.$watch(watchSpy); | ||
expect(watchSpy).to.not.be.called; | ||
expect(watchSpy).to.not.have.been.called; | ||
@@ -115,5 +115,8 @@ var listener = sinon.spy(); | ||
primus.emit('customEvent'); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listener).to.be.called; | ||
expect(watchSpy).to.be.called; | ||
expect(listener, 'listener').to.have.been.called; | ||
expect(watchSpy, 'watch').to.have.been.called; | ||
}); | ||
@@ -127,2 +130,3 @@ | ||
primus.emit('customEvent'); | ||
$rootScope.$digest(); | ||
@@ -163,2 +167,6 @@ expect(myListener).to.not.be.called; | ||
primus.emit('customEvent', {itemId: 1}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -174,2 +182,4 @@ | ||
}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -183,2 +193,5 @@ }); | ||
primus.emit('customEvent', {itemId: 11}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -188,2 +201,3 @@ | ||
primus.emit('customEvent', {id: 1}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -193,2 +207,3 @@ | ||
primus.emit('customEvent', 42); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -203,2 +218,5 @@ }); | ||
primus.emit('customEvent', {content: {id: 1}}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -215,2 +233,3 @@ | ||
}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -224,2 +243,5 @@ }); | ||
primus.emit('customEvent', {content: {id: 11}}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -229,2 +251,3 @@ | ||
primus.emit('customEvent', {content: {itemId: 1}}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -234,2 +257,3 @@ | ||
primus.emit('customEvent', 42); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -244,2 +268,5 @@ }); | ||
primus.emit('customEvent', {id: 1, content: {id: 1}}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -257,2 +284,3 @@ | ||
}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -266,2 +294,5 @@ }); | ||
primus.emit('customEvent', {id: 11, content: {id: 1}}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -271,2 +302,3 @@ | ||
primus.emit('customEvent', {id: 1, content: {id: 11}}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -276,2 +308,3 @@ | ||
primus.emit('customEvent', {id: 1}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -281,2 +314,3 @@ | ||
primus.emit('customEvent', {content: {id: 1}}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -286,2 +320,3 @@ | ||
primus.emit('customEvent', 42); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -302,2 +337,5 @@ }); | ||
primus.emit('customEvent', {id: 1}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -307,2 +345,3 @@ | ||
primus.emit('customEvent', {id: 3}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -315,5 +354,9 @@ }); | ||
primus.emit('customEvent', {id: 0}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
primus.emit('customEvent', {id: 20}); | ||
primus.emit('customEvent', {id: 20}); | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -325,3 +368,3 @@ }); | ||
it('when calling callback, should wrap it in $rootScope.$apply', function () { | ||
it('when calling callback, should call it in Angular context', function () { | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -332,3 +375,6 @@ expect(watchSpy, 'watchSpy').to.not.have.been.called; | ||
primus.emit('customEvent', {id: 1}); | ||
// thanks to $evalAsync, listener exec is scheduled in an angular timeout, | ||
// which won't happen in tests. Trigger it : | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.have.been.calledOnce; | ||
@@ -339,3 +385,3 @@ expect(digestWasInProgress).to.be.true; | ||
it('when NOT calling callback, should NOT call $rootScope.$apply', function () { | ||
it('when NOT calling callback, should NOT trigger a $rootScope $digest', function () { | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
@@ -347,4 +393,7 @@ expect(watchSpy, 'watchSpy').to.not.have.been.called; | ||
expect(watchSpy, 'watchSpy').to.not.have.been.called; | ||
$rootScope.$digest(); | ||
expect(listenerSpy, 'listenerSpy').to.not.have.been.called; | ||
expect(watchSpy, 'watchSpy').to.not.have.been.called; | ||
expect(watchSpy, 'watchSpy').to.have.been.calledTwice; // still, due to our explicit $rootScope.$digest | ||
}); | ||
@@ -357,2 +406,3 @@ | ||
primus.emit('customEvent', {id: 1}); | ||
$rootScope.$digest(); | ||
@@ -359,0 +409,0 @@ expect(listenerSpy, 'listenerSpy').to.not.have.been.called; |
Sorry, the diff of this file is not supported yet
26362
546
84