KnockoutFire map Firebase json structure into HTML structure using KnockoutJs.
Latest release may have breaking changes.
I recommend to use versioned release, like 0.0.5 instead.
<script type="text/javascript" src="//hiroshi.github.io/knockoutFire/knockoutfire-0.0.5.js"></script>
Also see CHANGELOG.
In bower.json or component.json.
"dependencies": {
...
"knockoutfire": "git://github.com/hiroshi/knockoutFire.git"
}
This will fetch latest tag.
items: {
-XXX: {
content: "Hello"
}
-YYY: {
content: "World."
}
}
<div id="viewModel">
<ul data-bind="foreach: items">
<li data-bind="text: content"></li>
</ul>
</div>
var firebase = new Firebase("https://knockoutFire-README-example.firebaseio-demo.com");
var viewModel = KnockoutFire.observable(firebase, {
items: {
"$item": {
content: true,
}
}
});
ko.applyBindings(viewModel, document.getElementById("viewModel"));
The notation resembles to Firebase Security Rule.
You need to specify which properties are used as observable properties of view models. KnockoutFire will retrieve only what specified in the map.
- Each properties will be a
ko.observable()
and synchronized with the corresponding value in Firebase.
person: {
firstName: true,
lastName: true
}
If you use a property name start with $
, the parent property will be ko.observableArray()
.
users: {
"$user": {
nickname: true,
}
}
For add/remove/move operations, you should use Firebase API instead of manipulating observable array directly.
users()[1]().firebase.remove();
If you need reverse order;
comments: {
".reverse": true,
"$comment": {
content: true
}
}
comments: {
".startAt": 0,
".endAt": {
".priority": 100,
".name": "foo"
},
".limit": 20
}
"startAt": 1
->startAt(1)
"startAt": {".priority": 1, ".name": "hiroshi"}
->startAt(1, "hiroshi")
"startAt": undefined
->startAt()
For more information, Querying and Limiting Data in Firebase | Firebase Documentation.
.newItem
adds additional sub viewModel to an observable array.
comments: {
".newItem": true,
"$comment": {
content: true
}
}
<div data-bind="with: comments.newItem">
<form data-bind="submit: create">
<input type="text" data-bind="value: content">
<input type="submit">
</form>
</div>
If you need a priority
to be set;
".newItem": {
".priority": function() { return Date.now() }
}
If you need a default value rather than from a data-bind;
".newItem": {
isdone: function(){ return false; }
}
If you need a callback on success;
".newItem": {
".on_success": function(){ do_someting(); }
}
To use Denormalized data use .indexOf
.
members: {
"$user": {
".indexOf": "/users/$user",
"nickName": true
}
}
You can access nickName like this:
members()[0]().nickName()
You can use Knockout extender.
ko.extenders.person = function(self, option) {
self.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
});
};
Then specify the extender by name:
person: {
firstName: true,
lastName: true,
".extend": {person: true}
}