Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角虫。ngif在一种方法中不起作用_Angular_Angular Ng If - Fatal编程技术网

Angular 角虫。ngif在一种方法中不起作用

Angular 角虫。ngif在一种方法中不起作用,angular,angular-ng-if,Angular,Angular Ng If,我的程序中出现了一个奇怪的bug,使得*ngIf停止工作 我的方法: stripeSubmit(){ this.stripeCheckout = false; // removes the form this.isLoading = true; // shows a loading spinner ... this.api.chargeCard(charge).subscribe(res =>{ if

我的程序中出现了一个奇怪的bug,使得*ngIf停止工作

我的方法:

stripeSubmit(){
    this.stripeCheckout = false;   // removes the form 
    this.isLoading = true;         // shows a loading spinner
       ...
        this.api.chargeCard(charge).subscribe(res =>{ 
          if(res === "Success"){
            this.api.submitOrder(this.orderObj).subscribe(res =>{
              this.isLoading = false;              // not working
              sessionStorage.clear();
              this.router.navigate(['/thank-you']) // is working but still displays /cart on top
            });
          }else {
            console.log("ELSE condition"); // works
            alert(res);                    // works
            this.stripeFailBoolean = true; // doesn't work
            this.stripeCheckout = true;    // doesn't work
            this.isLoading = false;        // doesn't work
            console.log(this.isLoading);   // logs "false"
          }
        })
      }
    });
 }
HTML:

。。。
你的车
...
出现问题,请重试
信用卡

到期月份
到期年
CVC
提交
正如上面注释掉的部分所示,当我单击submit时,表单将消失,微调器将启动。如果chargeCard方法成功,h1和加载微调器将保留,并且“/thank-you”的内容将显示在其下方(URL显示“/thank-you”)

如果该方法未通过if语句,则警报和日志将起作用,但3个布尔值均不起作用,微调器将无限期运行

我试着把我所有的布尔人都放在一个ngDoCheck上,但那根本没用

有人知道为什么我的布尔函数会起作用,除非在这个方法中? 谢谢

*****编辑: 如果愿意,您可以自己复制错误:

在船底租一艘船,然后去购物车

如果交易成功,请使用信用卡: 4242 4242 4242 4242 12/2024 123

如果资金不足,请使用信用卡: 4000 0000 0000 9995 12/2024 123

代码在

***********编辑2

以下是Stackblitz的代码:

Cart组件给我带来了麻烦,因为它是一个3ed party工具,并且似乎没有与Angular集成(当你在访问Stripe对象之前将
窗口
投射到任何对象时,在回购协议中在线判断),我想说,这种意外行为是由在外部运行代码引起的

简单地说,如果您的代码调用某些代码作为某个外部代码的回调,Angular可能不知道代码已运行。这意味着Angular不知道某些值已更改->它不会触发更改检测->它没有正确刷新页面

导航为什么起作用?因为
createToken
的回调中的代码导航到
https://www.howlingwolfe.com/thank-you
。当URL更改时,将使用匹配组件。Angular不会更新视图,但会在URL更改时加载新组件

为什么
console.log(this.isLoading)正在工作吗?担心变量值的更新不是Angular的一部分。Angular不知道您更改了值,但在代码中您肯定更改了值,因此
console.log
将打印正确的值。它将被更改,但如果在区域外执行,Angular将不会做任何事情

现在如何解决它:将
NgZone
注入构造函数,并将整个代码(从第行开始)包装到
中。\NgZone.run()
。您可以按照文档中提供的步骤进行操作

另一个问题可能是您正在订阅。我这里没有支持我的文档。主要原因是在订阅中从内部订阅取消订阅变得很棘手(公平地说,您至少应该为每个订阅使用
takeUntil(unsubscribe$)
(因此
…管道(takeUntil(this.unsubscribe$))。订阅(…)

下一步将是不进行内部订阅——这是更高的可观察性发挥作用的时候

举个例子,你应该避免这样做:

this.api.chargeCard(charge).subscribe(res1 => { 
    if (res1 === "Success") {
        this.api.submitOrder(this.orderObj).subscribe(res2 => {...})
    }
})
this.api.chargeCard(charge).pipe(
    switchMap((res1: string) => res1 === "Success" 
        ? this.api.submitOrder(this.orderObj).pipe(tap(/* do Your code here, clear and navigate*/)) 
        : of(res1).pipe(tap(/* do Your code here on failure))),
    finalize(() => this.isLoading = false),
    takeUntil(this.unsubscribe$)
).subscribe()
这样做:

this.api.chargeCard(charge).subscribe(res1 => { 
    if (res1 === "Success") {
        this.api.submitOrder(this.orderObj).subscribe(res2 => {...})
    }
})
this.api.chargeCard(charge).pipe(
    switchMap((res1: string) => res1 === "Success" 
        ? this.api.submitOrder(this.orderObj).pipe(tap(/* do Your code here, clear and navigate*/)) 
        : of(res1).pipe(tap(/* do Your code here on failure))),
    finalize(() => this.isLoading = false),
    takeUntil(this.unsubscribe$)
).subscribe()

非常感谢@Eatos!!NgZone绝对是一个不错的选择。以下是新的工作方法:

stripeSubmit(){
    this.stripeCheckout = false;
    this.isLoading = true;
    this.stripeFailBoolean = false;

    (<any>window).Stripe.card.createToken({
      number: this.cardNumber,
      exp_month: this.expMonth,
      exp_year: this.expYear,
      cvc: this.cvc
    }, (status: number, response: any) => {
      this.ngZone.run(() => {
      if (status === 200) {
        let charge: Charge = {
          token: response.id,
          price: this.total
        }
        // this.chargeCard(token);
        this.api.chargeCard(charge).pipe(takeUntil(this.unsubscibe), tap(()=>{
          console.log('inside of charge card tap');
          
          
        }), switchMap((res: any)=>{
          if(res === "Success"){
            return this.api.submitOrder(this.orderObj).pipe(tap(()=>{
              this.isLoading = false;
              sessionStorage.clear();
              this.router.navigate(['/thank-you'])              
            }))
          } else {
            return of(res).pipe(tap(()=>{
            this.stripeFailText = res;
            this.stripeFailBoolean = true;
            this.stripeCheckout = true;
            this.isLoading = false;
            }))
          }
          
        })).subscribe();
      }else {
        console.log(response.error.message);
        
      }
      console.log('ngZone leave');
    })
  }); 
  }   
 
  ngOnDestroy(){
    this.unsubscibe.next();
    this.unsubscibe.complete();
  }

stripeSubmit(){
this.stripeCheckout=false;
this.isLoading=true;
this.stripeFailBoolean=false;
(窗口).Stripe.card.createToken({
号码:这个。卡号,
exp_month:this.expMonth,
exp_year:this.expYear,
这个
},(状态:编号,响应:任意)=>{
此.ngZone.run(()=>{
如果(状态===200){
充电:充电={
令牌:response.id,
价格:这个
}
//这是一张充值卡(代币);
this.api.chargeCard(charge).pipe(takeUntil(this.unsubsibe)),点击(()=>{
console.log('收费卡抽头内部');
}),switchMap((res:any)=>{
如果(res==“成功”){
返回this.api.submitor(this.orderObj.pipe)(点击(()=>{
this.isLoading=false;
sessionStorage.clear();
这个.router.navigate(['/thank-you'])
}))
}否则{
返回(res).管道(分接头(()=>{
this.stripeFailText=res;
this.stripeFailBoolean=true;
this.stripeCheckout=true;
this.isLoading=false;
}))
}
})).subscribe();
}否则{
console.log(response.error.message);
}
控制台日志('ngZone leave');
})
}); 
}   
恩贡德斯特罗(){
this.unsubsibe.next();
this.unsubsibe.complete();
}

您可以创建一个更好地说明问题的方法吗?您也可以尝试使用我添加的live站点重新创建它,以便可以复制错误。stackblitz似乎无法正常工作,但我会继续尝试,非常感谢您的深思熟虑的回复!不幸的是,我在测试应用程序时仍然得到相同的行为n、 也许我没有使用tap对吗?我已经尝试了
tap(()=>{/*mycode*/})
tap({complete:()=>{/*mycode*/}}})
但是两者都给了我相同的结果。在
tap()
内部的代码应该是什么样子?谢谢!我没有