From 0da8f3f04ed7e05cf9d17d195b0662278533280c Mon Sep 17 00:00:00 2001 From: wangxiao Date: Fri, 14 Jul 2017 18:16:20 +0800 Subject: [PATCH 1/4] $createObservableFunction --- example/counter-function.html | 73 +++++++++++++++++++++++++ src/index.js | 2 + src/methods/createObservableFunction.js | 57 +++++++++++++++++++ test/test.js | 34 ++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 example/counter-function.html create mode 100644 src/methods/createObservableFunction.js diff --git a/example/counter-function.html b/example/counter-function.html new file mode 100644 index 0000000..17f2d78 --- /dev/null +++ b/example/counter-function.html @@ -0,0 +1,73 @@ + + + + + + +
+
{{ count }}
+ + + + + + + + + +
{{ $data }}
+ + +
+ + diff --git a/src/index.js b/src/index.js index 461a93d..11822ae 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import watchAsObservable from './methods/watchAsObservable' import fromDOMEvent from './methods/fromDOMEvent' import subscribeTo from './methods/subscribeTo' import eventToObservable from './methods/eventToObservable' +import createObservableFunction from './methods/createObservableFunction' export default function VueRx (Vue, Rx) { install(Vue, Rx) @@ -16,6 +17,7 @@ export default function VueRx (Vue, Rx) { Vue.prototype.$fromDOMEvent = fromDOMEvent Vue.prototype.$subscribeTo = subscribeTo Vue.prototype.$eventToObservable = eventToObservable + Vue.prototype.$createObservableFunction = createObservableFunction } // auto install diff --git a/src/methods/createObservableFunction.js b/src/methods/createObservableFunction.js new file mode 100644 index 0000000..626de1a --- /dev/null +++ b/src/methods/createObservableFunction.js @@ -0,0 +1,57 @@ +import { Rx, hasRx, warn } from '../util' + +/** + * @name vue.prototype.$createObservableFunction + * @description Creates an observable from a given function name. + * @param {String} functionName Function name + * @param {Boolean} [passContext] Append the call context at the end of emit data? + * @return {Observable} Hot stream + */ +export default function createObservableFunction (functionName, passContext) { + if (!hasRx()) { + return + } + const vm = this + + if (!Rx.Observable.prototype.share) { + warn( + `No 'share' operator. ` + + `$createObservableFunction returns a shared hot observable. ` + + `Try import 'rxjs/add/operator/share' for creating ${functionName}`, + vm + ) + return + } + + if(vm[functionName] !== undefined){ + warn( + 'Potential bug: ' + + `Method ${functionName} already defined on vm and has been overwritten by $createObservableFunction.` + + String(vm[functionName]), + vm + ) + } + + let creator = function (observer) { + + vm[functionName] = function () { + let args = Array.from(arguments); + if(passContext){ + args.push(this); + observer.next(args); + }else{ + if (args.length <= 1) { + observer.next(args[0]); + } else { + observer.next(args); + } + } + }; + return function() { + delete vm[functionName]; + }; + }; + + //Must be a hot stream otherwise function context may overwrite over and over again + return Rx.Observable.create(creator).share(); +} diff --git a/test/test.js b/test/test.js index 8ea674c..6e79217 100644 --- a/test/test.js +++ b/test/test.js @@ -10,6 +10,7 @@ const Observable = require('rxjs/Observable').Observable const Subject = require('rxjs/Subject').Subject const Subscription = require('rxjs/Subscription').Subscription require('rxjs/add/observable/fromEvent') +require('rxjs/add/operator/share') // user require('rxjs/add/operator/map') @@ -316,3 +317,36 @@ test('$eventToObservable() with lifecycle hooks', done => { vm.$destroy() }) }) + + +test('$createObservableFunction() with no context', done => { + const vm = new Vue({ + created () { + this.$createObservableFunction('add') + .subscribe(function (param) { + expect(param).toEqual('hola') + done(param) + }) + } + }) + nextTick(() => { + vm.add('hola') + }) +}) + +test('$createObservableFunction() with muli params & context', done => { + const vm = new Vue({ + created () { + this.$createObservableFunction('add',true) + .subscribe(function (param) { + expect(param[0]).toEqual('hola') + expect(param[1]).toEqual('mundo') + expect(param[2]).toEqual(vm) + done(param) + }) + } + }) + nextTick(() => { + vm.add('hola','mundo') + }) +}) From b9f6144550c26dcc17555e38918f22d9d66e0c78 Mon Sep 17 00:00:00 2001 From: wangxiao Date: Fri, 14 Jul 2017 18:51:12 +0800 Subject: [PATCH 2/4] readme y version --- README.md | 23 +++++++++++++++++++++++ package.json | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bc8752a..ca3e6f4 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,29 @@ var vm = new Vue({ }) ``` +#### `$createObservableFunction(functionName)` + +> This feature requires RxJS. + +Convert function calls to observable sequence which emits the call arguments. + +This is a prototype method added to instances. Use it to create a shared hot observable from a function name. The function body will assigned to vm. + +```html + +``` +``` js +var vm = new Vue({ + subscriptions () { + return { + formData: this.$createObservableFunction('submitHandler') + } + } +}) +``` +[example](https://github.com/vuejs/vue-rx/blob/master/example/counter-function.html) + + ### Caveats You cannot use the `watch` option to watch subscriptions, because it is processed before the subscriptions are set up. But you can use `$watch` in the `created` hook instead. diff --git a/package.json b/package.json index fe71d31..a9e5132 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-rx", - "version": "3.2.0", + "version": "3.3.0", "description": "RxJS bindings for Vue", "main": "dist/vue-rx.js", "files": [ From f47ef071fd2b3042b9e1b8df3909dc2866df247a Mon Sep 17 00:00:00 2001 From: wangxiao Date: Fri, 14 Jul 2017 19:03:05 +0800 Subject: [PATCH 3/4] indent --- src/methods/createObservableFunction.js | 35 ++++++++++++------------- test/test.js | 5 ++-- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/methods/createObservableFunction.js b/src/methods/createObservableFunction.js index 626de1a..faa4935 100644 --- a/src/methods/createObservableFunction.js +++ b/src/methods/createObservableFunction.js @@ -1,7 +1,7 @@ import { Rx, hasRx, warn } from '../util' /** - * @name vue.prototype.$createObservableFunction + * @name Vue.prototype.$createObservableFunction * @description Creates an observable from a given function name. * @param {String} functionName Function name * @param {Boolean} [passContext] Append the call context at the end of emit data? @@ -23,7 +23,7 @@ export default function createObservableFunction (functionName, passContext) { return } - if(vm[functionName] !== undefined){ + if (vm[functionName] !== undefined) { warn( 'Potential bug: ' + `Method ${functionName} already defined on vm and has been overwritten by $createObservableFunction.` + @@ -32,26 +32,25 @@ export default function createObservableFunction (functionName, passContext) { ) } - let creator = function (observer) { - + const creator = function (observer) { vm[functionName] = function () { - let args = Array.from(arguments); - if(passContext){ - args.push(this); - observer.next(args); - }else{ + const args = Array.from(arguments) + if (passContext) { + args.push(this) + observer.next(args) + } else { if (args.length <= 1) { - observer.next(args[0]); + observer.next(args[0]) } else { - observer.next(args); + observer.next(args) } } - }; - return function() { - delete vm[functionName]; - }; - }; + } + return function () { + delete vm[functionName] + } + } - //Must be a hot stream otherwise function context may overwrite over and over again - return Rx.Observable.create(creator).share(); + // Must be a hot stream otherwise function context may overwrite over and over again + return Rx.Observable.create(creator).share() } diff --git a/test/test.js b/test/test.js index 6e79217..2dea9a8 100644 --- a/test/test.js +++ b/test/test.js @@ -318,7 +318,6 @@ test('$eventToObservable() with lifecycle hooks', done => { }) }) - test('$createObservableFunction() with no context', done => { const vm = new Vue({ created () { @@ -337,7 +336,7 @@ test('$createObservableFunction() with no context', done => { test('$createObservableFunction() with muli params & context', done => { const vm = new Vue({ created () { - this.$createObservableFunction('add',true) + this.$createObservableFunction('add', true) .subscribe(function (param) { expect(param[0]).toEqual('hola') expect(param[1]).toEqual('mundo') @@ -347,6 +346,6 @@ test('$createObservableFunction() with muli params & context', done => { } }) nextTick(() => { - vm.add('hola','mundo') + vm.add('hola', 'mundo') }) }) From 5c8f9c3d424ae7316a9f75d39094aa6214515e14 Mon Sep 17 00:00:00 2001 From: wangxiao Date: Wed, 26 Jul 2017 10:23:56 +0800 Subject: [PATCH 4/4] add observableMethods --- README.md | 13 ++++-- example/counter-function.html | 40 ++++-------------- src/index.js | 4 +- ...eFunction.js => createObservableMethod.js} | 20 ++++----- src/mixin.js | 13 ++++++ test/test.js | 42 +++++++++++++++++-- 6 files changed, 80 insertions(+), 52 deletions(-) rename src/methods/{createObservableFunction.js => createObservableMethod.js} (62%) diff --git a/README.md b/README.md index ca3e6f4..97dac29 100644 --- a/README.md +++ b/README.md @@ -241,13 +241,13 @@ var vm = new Vue({ }) ``` -#### `$createObservableFunction(functionName)` +#### `$createObservableMethod(methodName)` > This feature requires RxJS. Convert function calls to observable sequence which emits the call arguments. -This is a prototype method added to instances. Use it to create a shared hot observable from a function name. The function body will assigned to vm. +This is a prototype method added to instances. Use it to create a shared hot observable from a function name. The function will assigned as a vm method. ```html @@ -256,11 +256,18 @@ This is a prototype method added to instances. Use it to create a shared hot obs var vm = new Vue({ subscriptions () { return { - formData: this.$createObservableFunction('submitHandler') + // requires `share` operator + formData: this.$createObservableMethod('submitHandler') } } }) ``` +Or, use the `observableMethods` convenience option: +``` js +new Vue({ + observableMethods: { submitHandler:'submitHandler$' } +}) +``` [example](https://github.com/vuejs/vue-rx/blob/master/example/counter-function.html) diff --git a/example/counter-function.html b/example/counter-function.html index 17f2d78..6b5a06e 100644 --- a/example/counter-function.html +++ b/example/counter-function.html @@ -7,21 +7,13 @@
{{ count }}
- - + + - - - - +
{{ $data }}
-