如何使用Angular 2从Firebase 3方法中传递值

时间:2016-09-05 23:45:33

标签: angular typescript firebase firebase-realtime-database firebase-authentication

我刚刚开始学习Angular 2和Firebase,并且已经陷入了一个基本问题。

我正在使用Firebase createUserWithEmailAndPassword方法使用HTML表单数据注册新用户帐户,该表单数据存储在自定义登录类中,然后通过该方法存储。

这有效,但我无法弄清楚如何将我在错误对象中获得的任何错误数据传输到我的HTML模板以供显示。我已经在登录类中添加了变量,但我无法在createUserWithEmailAndPassword方法中访问它。

我知道这可能是基本的东西,但任何帮助都会非常有用。谢谢!

LoginComponent.ts

import { Component } from "@angular/core";
import { Router }    from "@angular/router";

import { Login }     from "./login";

@Component({
    selector: 'login-component',  
    templateUrl: 'app/login/login.component.html',
    styleUrls:[
        'app/login/login.component.css'
    ]
})

export class LoginComponent{

    login = new Login('James', 'SuperSecret', false, '');
    submitted = false;

    onSubmit(){this.submitted= true};

    active = true;

    newUser(){
                    firebase.auth().createUserWithEmailAndPassword(this.login.email, this.login.pswd).catch(function(error) {
            if(error){
                console.log('The error code: ' + error.code + '\nThe error message' + error.message);
                this.login.error = true;
                this.login.errorMsg = error.message;
            }else{
                this.login.error=false;
                this.login.errorMsg='';
            }                
        });
    }

}

LoginComponent.html

<div class="container">
    <div [hidden]="submitted">
        <h1>Login Form</h1>
        <form *ngIf="active" (ngSubmit)="onSubmit()" #loginForm="ngForm">            

            <!--  Email Input  -->
            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" class="form-control" id="email" required 
                        [(ngModel)]="login.email" name="email" #email="ngModel">
                <div [hidden]="email.valid || email.pristine"
                        class="alert alert-danger">
                        Email is required
                </div>
            </div>

            <!--  Password Input  -->
            <div class="form-group">
                <label for="pswd">Password</label>
                <input type="password" class="form-control" id="pswd" [(ngModel)]="login.pswd" name="pswd" required>

                <!--  EXAMPLE ERROR DISPLAY  -->
                <div [hidden]="!login.error" class="alert alert-danger">{{login.errorMsg}}</div>
            </div>

             <!-- Submit Buttons  -->
            <button type="submit" class="btn btn-default" [disabled]="!loginForm.form.valid">Login</button>
            <button type="button" class="btn btn-default" (click)="newUser()">Register</button>
        </form>
    </div>
</div>

Login.ts(登录类)

export class Login{
    constructor(
        public email: string,
        public pswd:  string,
        public error: boolean,
        public errorMsg: string
    ){}
}

1 个答案:

答案 0 :(得分:1)

您的问题与firebase或promise api无关,但在this如何在javascript中工作方面存在一些非常普遍的错误。您假定在分配错误时访问LoginComponent但传递给catch()方法的函数并未将LoginComponent用作this。您最有可能在window对象上设置错误。

有几种方法可以解决这个问题。

绑定正确的:

newUser() {
  firebase.auth()
    .createUserWithEmailAndPassword(this.login.email, this.login.pswd)
    .catch(
      function(error) {
        this.login.errorMsg = error.message;
      }
      .bind(this)
    );
}

使用闭包:

newUser() {
  // capturing 'this' in a variable
  var self = this;
  firebase.auth()
    .createUserWithEmailAndPassword(this.login.email, this.login.pswd)
    .catch(
      function(error) {
        // using the captured this (in the self variable)
        self.login.errorMsg = error.message;
      }
    );
}

使用箭头函数(没有this参数,因此在外部范围内寻找this。这需要ES2015,因此您需要在定位旧浏览器时进行转换。当您使用TypeScript时,我建议使用此版本,因为它是最简洁的版本。

newUser() {
  firebase.auth()
    .createUserWithEmailAndPassword(this.login.email, this.login.pswd)
    .catch(
      (error) => {
        this.login.errorMsg = error.message;
        // further assignments
      }
    );
}

当你只需要执行一个动作时,你甚至可以通过省略括号来简化它:

newUser() {
  firebase.auth()
    .createUserWithEmailAndPassword(this.login.email, this.login.pswd)
    .catch(error => this.login.errorMsg = error.message);
}

顺便说一句:当使用基于promise的API时,在实现catch回调时不应检查错误是否存在应该是安全的,因为只有在出现错误时才会调用...

有关详细信息,请阅读有关thisHow to access the correct `this` context inside a callback?

的优秀答案