I setup a tiny sample app that edits one field. But when I type in that field the contents keep reverting back to a second ago. I'm looking for a fix to AngularFire that makes it just work, or a RTFM where I'm just not initializing it right. At this point bindTo() is not useable and I can't move forward on using AngularFire at all.
Here's the full sample (and you can open it at http://jsbin.com/wabafu/3):
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
<script src='https://cdn.firebase.com/js/client/1.0.19/firebase.js'></script>
<script src='https://cdn.firebase.com/libs/angularfire/0.8.0/angularfire.min.js'></script>
<script>
var app = angular.module("myapp", ["firebase"]);
function MyController($scope, $firebase) {
var ref = new Firebase("https://stackoverflow25331760.firebaseIO.com/"),
syncObject = $firebase(ref).$asObject();
syncObject.$bindTo($scope, "data");
}
</script>
</head>
<body ng-controller="MyController">
<h3>
<input type="checkbox" ng-model="EditMode"> Enable Editing
</h3>
<div ng-if="EditMode">
<input type="text" ng-model="data.SyncValue" style="width:100%">
</div>
<div ng-if="!EditMode">
{{data.SyncValue}}
</div>
</body>
</html>
It works smooth when only open in one browser, but when open in multiple, I can't type more than a word or two without the text contents reverting back to a few keystrokes ago and the cursor moving to the end of the field.
I imagine the events happening are:
Am I imagining the process wrong? What should I do to stop step 5?
P.S. While testing, I found I can work around #7 by typing only a few characters quickly and then waiting 2 seconds, repeat. That way the value doesn't change while the sync is echoing and my cursor won't jump.
P.P.S. To try to narrow it down, I've made a checkbox that controls if the data is displayed in a field, or just a read-only div. Even if the second browser is only displaying the data, this echo/reverting behavior still exists in the first browser. The only way for data to store in firebase correctly is if I only have one browser using it at a time.
I've had good success by adding a debounce onto the input.
<input type="text" ng-model="data.field"
ng-model-options="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }" />
Also, $bindTo isn't strictly necessary here. It's not particularly hard to manually save the data and skip the $bindTo.
$scope.data = $firebase(new Firebase(...)).$asObject();
<input type="text" ng-model="data.field" ng-blur="data.$save()" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With