I am trying to three-way bind an input element to firebase database in Angular.js 2 (2.0.0-rc.4), using AngularFire 2 (2.0.0-beta.2).
I have a very simple html like:
<form (ngSubmit)="onSubmit()" #commentForm="ngForm">
<input [(ngModel)]="model.author" type="input" name="author" required>
</form>
In my component, to save and retrieve contents of this input to firebase, I have an implementation like this:
export class CommentFormComponent implements OnInit, AfterViewInit {
@ViewChild("commentForm") form;
// http://stackoverflow.com/questions/34615425/how-to-watch-for-form-changes-in-angular-2
firebaseInitComplete = false;
model: Comment = new Comment("", "");
firebaseForm: FirebaseObjectObservable<Comment>;
constructor(private af: AngularFire) { }
ngAfterViewInit() {
this.form.control.valueChanges
.subscribe(values => {
// If we haven't get the initial value from firebase yet,
// values will be empty strings. And we don't want to overwrite
// real firebase value with empty string on page load
if (!this.firebaseInitComplete) { return; }
// If this is a change after page load (getting initial firebase value) update it on firebase to enable 3-way binding
this.firebaseForm.update(values);
});
}
ngOnInit() {
this.firebaseForm = this.af.database.object("/currentComment");
// Listen to changes on server
this.firebaseForm.subscribe(data => {
this.firebaseInitComplete = true; // Mark first data retrieved from server
this.model = data;
});
}
}
The code above works, I am able to read initial firebase value and update value on firebase when user type something in real time.
But having a manual logic to check for this.firebaseInitComplete
and adding ngAfterViewInit
to listen for changes feels a little bit wrong and I am just hacking it to work.
Is there a better implementation of three-way binding with less logic inside component?
The two-way data binding in Angular is used to display information to the end user and allows the end user to make changes to the underlying data using the UI. This makes a two-way connection between the view (the template) and the component class. This is similar to the two-way binding in WPF.
Difference between One-way & Two-way BindingIn one-way binding, the flow is one-directional. In a two-way binding, the flow is two-directional. This means that the flow of code is from ts file to Html file. This means that the flow of code is from ts file to Html file as well as from Html file to ts file.
AngularJS provides two types of Data Binding: One-way data binding. Two-way data binding.
To fix Can't bind to 'ngModel' since it isn't a known property of 'input' error in Angular applications we have to import FormModule in app. module. ts file. If you are using FormBuilder class to create reactive form we have to import ReactiveFormsModule as well to avoid below error.
Seven months later and I have an answer for you.. extended ngModel syntax..
<input [ngModel]='(model|async)?.author' (ngModelChange)="model.update({author: $event})">
The [] block is a getter and the () block is a setter. Since the model's getter is actually unwrapping the FirebaseObjectObservable, you have to use the FirebaseObjectObservable's binding to set it.
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