【问题标题】:How to export variable from function in Angular?如何从Angular中的函数导出变量?
【发布时间】:2019-11-21 13:49:57
【问题描述】:

当我在函数内部定义变量时,我不能在外部使用它。

我试图在NgOnInit 中定义一个变量,它也不起作用。

我的代码:

addLink() {
    if(
      this.product.name !== '' && 
      this.product.price !== 0 && 
      this.product.instaURL !== '') {
        firebase.auth().onAuthStateChanged(function(user) {
          if (user) {
            let uid = user.uid;
            console.log(uid)  //THIS WORK
          }
        });      
      console.log(uid); //THIS DONT WORK
      this.productService.addProduct(this.product);      
      this.product = {} as Product;
    }
  }

我得到的错误:

TS2304:找不到名称“uid”。

【问题讨论】:

标签: javascript node.js typescript firebase firebase-authentication


【解决方案1】:

这是因为声明为let 的变量的范围受到它们定义的块的限制,要使用它,您只需在函数范围之外声明它即可。

addLink() {
if(
  this.product.name !== '' && 
  this.product.price !== 0 && 
  this.product.instaURL !== '') {
    let uid;
    firebase.auth().onAuthStateChanged(function(user) {
      if (user) {
        uid = user.uid;
        console.log(uid)  //THIS WORK
      }
    });      
  console.log(uid); //THIS ALSO WORKS ;)
  this.productService.addProduct(this.product);      
  this.product = {} as Product;
}

}

【讨论】:

  • 我强烈反对在 typescript/angular 中使用 var,让我们记住范围和非提升,使用 var 我们最终会混合使用。
  • 我没有意识到这是在 Typescript 中运行的,很抱歉。
  • 没问题,它确实发生了.. 只是要更加小心,因为有时我们最终可能会提供一些错误信息
【解决方案2】:

上面的代码运行正常。在函数内部使用“让”它只是暂时的。而是在声明类后立即创建一个变量:

export class FooBatComponent implements OnInit {
uid: number;

...

addLink() {
    if(
      this.product.name !== '' && 
      this.product.price !== 0 && 
      this.product.instaURL !== '') {
        firebase.auth().onAuthStateChanged(function(user) {
          if (user) {
            this.uid = user.uid;
            console.log(this.uid)  
          }
        });      
      this.productService.addProduct(this.product);      
      this.product = {} as Product;
    }
  }

【讨论】:

  • 抛出此错误:ERROR 错误:未捕获(在承诺中):TypeError:无法设置未定义的属性“uid” TypeError:无法设置未定义的属性“uid”
【解决方案3】:

因为uid 是一个块作用域变量。您可以从here 了解有关变量范围的更多信息。您还可以在代码中进行以下更改,以使 uid 超出 if 条件

addLink() {
    let uid;
    if(this.product.name !== '' && this.product.price !== 0 && this.product.instaURL !== '') {
     firebase.auth().onAuthStateChanged(function(user) {
       if (user) {
         uid = user.uid;
         console.log(uid)  //THIS WORK
       }
     });      
    console.log(uid); //THIS WILL WORK TOO
    this.productService.addProduct(this.product);      
    this.product = {} as Product;
 }
}

【讨论】:

  • 现在我没有任何错误,但函数外的console.log中的“uid”未定义
  • 是的,因为 uid 变量不是全局定义的。您需要在构造函数之前添加变量以使其成为全局变量,就像代码中的 product 变量一样
  • 请尝试Dan给出的答案。这正是你所需要的
  • 抛出此错误:ERROR 错误:未捕获(在承诺中):TypeError:无法设置未定义的属性“uid” TypeError:无法设置未定义的属性“uid”
  • 是的,因为您使用的是 function 关键字。您需要使用粗箭头函数在函数中获取this。您的 firebase 代码将如下所示 firebase.auth().onAuthStateChanged((user)=> { if (user) { this.uid = user.uid; console.log(this.uid) } });
【解决方案4】:

你需要先了解作用域的东西,每当你在一个块内用 let 声明一个变量时,它变成了块级作用域并且只在那个块内可用,在更高级别的作用域定义东西来使用那个变量。

【讨论】:

    【解决方案5】:

    这是一个函数范围问题。您必须在回调函数之外声明let uid

    而且,您需要使用arrow functionbind 将其保留在函数上下文中,以防止出现Cannot set property 'uid' of undefined TypeError: Cannot set property 'uid' of undefined 错误。

    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.uid = user.uid;
        console.log(this.uid)  
      }
    });  
    

    firebase.auth().onAuthStateChanged(function(user) {
      if (user) {
        this.uid = user.uid;
        console.log(this.uid)  
      }
    }.bind(this)); 
    

    阅读更多mdn doc

    let 允许您声明仅限于块语句范围或使用它的表达式的变量

    export class FooBatComponent implements OnInit {
    uid: number;
    
    ...
    
    addLink() {
      if (this.product.name !== '' && 
        this.product.price !== 0 && 
        this.product.instaURL !== '') {
          firebase.auth().onAuthStateChanged(user => {
            if (user) {
              this.uid = user.uid;
              console.log(this.uid)  
            }
          });      
          console.log(this.uid);
          this.productService.addProduct(this.product);      
          this.product = {} as Product;
       }
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多