Skip to content

Commit b1f3f6d

Browse files
committed
improve binding strategy
1 parent eda640d commit b1f3f6d

File tree

2 files changed

+29
-26
lines changed

2 files changed

+29
-26
lines changed

examples/todoApp/index.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="utf-8">
55
<title>VueFire Todo App Demo</title>
66
<script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>
7-
<script src="https://cdn.jsdelivr.net/vue/1.0.13/vue.js"></script>
7+
<script src="https://cdn.jsdelivr.net/vue/1.0.20/vue.js"></script>
88
<script src="../../dist/vuefire.js"></script>
99
</head>
1010
<body>
@@ -24,24 +24,26 @@
2424

2525
<script>
2626
/* global Vue, Firebase */
27+
var itemsRef = new Firebase('https://ReactFireTodoApp.firebaseio.com/items/')
28+
2729
new Vue({
2830
el: '#app',
2931
data: {
3032
newTodo: ''
3133
},
3234
firebase: {
3335
items: {
34-
source: new Firebase('https://ReactFireTodoApp.firebaseio.com/items/').limitToLast(25),
36+
source: itemsRef.limitToLast(25),
3537
asArray: true
3638
}
3739
},
3840
methods: {
3941
removeTodo: function (key) {
40-
this.$firebaseRefs.items.child(key).remove()
42+
itemsRef.child(key).remove()
4143
},
4244
addTodo: function () {
4345
if (this.newTodo.trim()) {
44-
this.$firebaseRefs.items.push({
46+
itemsRef.push({
4547
text: this.newTodo
4648
})
4749
this.newTodo = ''

src/vuefire.js

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
let Vue // late binding
2+
13
/**
24
* Check if a value is an object.
35
*
@@ -43,13 +45,12 @@ function indexForKey (array, key) {
4345
* Bind a firebase data source to a key on a vm.
4446
*
4547
* @param {Vue} vm
46-
* @param {object} data
4748
* @param {string} key
4849
* @param {object} source
4950
*/
50-
function bind (vm, data, key, source) {
51+
function bind (vm, key, source) {
5152
if (!isObject(source)) {
52-
throw new Error('Invalid Firebase binding source')
53+
throw new Error('VueFire: invalid Firebase binding source.')
5354
}
5455
var asArray = false
5556
var cancelCallback = null
@@ -68,23 +69,23 @@ function bind (vm, data, key, source) {
6869
vm._firebaseSources[key] = source
6970
// bind based on initial value type
7071
if (asArray) {
71-
bindAsArray(vm, data, key, source, cancelCallback)
72+
bindAsArray(vm, key, source, cancelCallback)
7273
} else {
73-
bindAsObject(vm, data, key, source, cancelCallback)
74+
bindAsObject(vm, key, source, cancelCallback)
7475
}
7576
}
7677

7778
/**
7879
* Bind a firebase data source to a key on a vm as an Array.
7980
*
8081
* @param {Vue} vm
81-
* @param {object} data
8282
* @param {string} key
8383
* @param {object} source
8484
* @param {function|null} cancelCallback
8585
*/
86-
function bindAsArray (vm, data, key, source, cancelCallback) {
87-
var array = data[key] = []
86+
function bindAsArray (vm, key, source, cancelCallback) {
87+
var array = []
88+
Vue.util.defineReactive(vm, key, array)
8889

8990
var onAdd = source.on('child_added', function (snapshot, prevKey) {
9091
var index = prevKey ? indexForKey(array, prevKey) + 1 : 0
@@ -120,13 +121,12 @@ function bindAsArray (vm, data, key, source, cancelCallback) {
120121
* Bind a firebase data source to a key on a vm as an Object.
121122
*
122123
* @param {Vue} vm
123-
* @param {object} data
124124
* @param {string} key
125125
* @param {Object} source
126126
* @param {function|null} cancelCallback
127127
*/
128-
function bindAsObject (vm, data, key, source, cancelCallback) {
129-
data[key] = {}
128+
function bindAsObject (vm, key, source, cancelCallback) {
129+
Vue.util.defineReactive(vm, key, {})
130130
var cb = source.on('value', function (snapshot) {
131131
vm[key] = snapshot.val()
132132
}, cancelCallback)
@@ -154,15 +154,8 @@ var VueFireMixin = {
154154
this.$firebaseRefs = Object.create(null)
155155
this._firebaseSources = Object.create(null)
156156
this._firebaseListeners = Object.create(null)
157-
// wrap data fn
158-
var vm = this
159-
var getData = this.$options.data
160-
this.$options.data = function () {
161-
var data = getData()
162-
for (var key in bindings) {
163-
bind(vm, data, key, bindings[key])
164-
}
165-
return data
157+
for (var key in bindings) {
158+
bind(this, key, bindings[key])
166159
}
167160
},
168161
beforeDestroy: function () {
@@ -178,13 +171,21 @@ var VueFireMixin = {
178171
/**
179172
* Install function passed to Vue.use() in manual installation.
180173
*
181-
* @param {function} Vue
174+
* @param {function} _Vue
182175
*/
183-
function install (Vue) {
176+
function install (_Vue) {
177+
Vue = _Vue
184178
Vue.mixin(VueFireMixin)
185179
// use object-based merge strategy
186180
var mergeStrats = Vue.config.optionMergeStrategies
187181
mergeStrats.firebase = mergeStrats.methods
182+
// extend instance methods
183+
Vue.prototype.$bind = function (key, source) {
184+
bind(this, key, source)
185+
}
186+
Vue.prototype.$unbind = function (key) {
187+
unbind(this, key)
188+
}
188189
}
189190

190191
// auto install

0 commit comments

Comments
 (0)