2017-09-24 48 views
0

以下是一些代码段。这个模式(afaik)适用于英雄教程。* ngIf对布尔变化没有反应

login.component.html:

login.component.ts:

wrongCredentialsInserted: boolean = false; 

//...  

onSubmit(login: LoginDto): void { 
     console.log(`User '${login.username}' attempts to login...`); 
     if (this.authService.login(login.username, login.password)) { 
      this.location.back(); 
     } else { 
      this.wrongCredentialsInserted = true; //This line gets executed! 
     } 
     } 

没有得到该信息显示,即使我设置wrongCredentialsInserted为true。它被设置为true,我已经验证了这一点。我还尝试了*ngIf="wrongCredentialsInserted === true"之类的东西,因为我在其他地方读过,但没有奏效。 我读到这可能与“以Angular 2开头的单向数据流”有关,但我知道我们能够在我们公司的A2 +项目中做这样的事情。 AFAIK单向数据绑定仅指组件通信。

任何形式的帮助,高度赞赏。

编辑:由于我所做的事似乎有点混乱,我在这里发布整个文件。

login.component.ts

import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; 
import {routerTransition} from '../../router.transition'; 
import {Component} from '@angular/core'; 
import {AuthService} from '../auth.service'; 
import {LoginDto} from './login-dto'; 
import {Location} from '@angular/common'; 

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

    private readonly USERNAME: string = 'username'; 
    private readonly PASSWORD: string = 'password'; 

    myForm: FormGroup; 
    username: AbstractControl; 
    password: AbstractControl; 

    message: string; 
    wrongCredentialsInserted = false; 

    constructor(public fb: FormBuilder, 
       public authService: AuthService, 
       public location: Location) { 
    this.message = ''; 

    this.myForm = fb.group({ 
     username: ['', Validators.required], 
     password: ['', Validators.required] 
    }); 

    this.username = this.myForm.controls[this.USERNAME]; 
    this.password = this.myForm.controls[this.PASSWORD]; 
    } 

    onSubmit(login: LoginDto): void { 
    console.log(`User '${login.username}' attempts to login...`); 
    if (this.authService.login(login.username, login.password)) { 
     this.location.back(); 
    } else { 
     this.wrongCredentialsInserted = true; 
    } 
    } 

    login(username: string, password: string): boolean { 
    this.message = ''; 
    if (!this.authService.login(username, password)) { 
     this.message = 'Incorrect credentials.'; 
     setTimeout(
     function() { 
      this.message = ''; 
     }.bind(this), 2500); 
    } 
    return false; 
    } 

    logout(): boolean { 
    this.authService.logout(); 
    return false; 
    } 

} 

login.component.html

<div class="ui raised segment"> 
    <form [formGroup]="myForm" 
     (ngSubmit)="onSubmit(myForm.value)" 
     class="ui form" 
     [class.error]="!myForm.valid"> 

    <div class="field" 
     [class.error]="!username.valid && username.touched"> 
     <label for="username">Username:</label> 
     <input type="text" 
      id="username" 
      placeholder="Username" 
      [formControl]="username"> 
     <div *ngIf="username.hasError('required') && username.touched" 
      class="ui error message"> 
     Username is required 
     </div> 
    </div> 

    <div class="field" 
     [class.error]="!password.valid && username.touched"> 
     <label for="password">Password:</label> 
     <input type="text" 
      id="password" 
      placeholder="Password" 
      [formControl]="password"> 
     <div *ngIf="password.hasError('required') && password.touched" 
      class="ui error message">Password is required 
     </div> 
    </div> 

    <div class="ui grid"> 

     <div class="two wide column middle aligned"> 
     <button type="submit" 
     class="ui button" 
     [class.disabled]="!myForm.valid">Submit 
     </button> 
     </div> 

     <div class="fourteen wide column middle aligned" *ngIf="wrongCredentialsInserted"> 
     <div 
      class="ui error message">Invalid credentials 
      </div> 
     </div> 

     </div> 

    </form> 
    </div> 

login.component.css:空

auth.service.ts:

@Injectable() 
export class AuthService { 

    constructor(private http: Http) { 
    } 

    login(user: string, password: string): boolean { 
    if (user === 'user' && password === 'password') { 
     localStorage.setItem('username', user); 
     return true; 
    } 

    return false; 
    } 

    logout(): any { 
    localStorage.removeItem('username'); 
    } 

    getUser(): any { 
    return localStorage.getItem('username'); 
    } 

    isLoggedIn(): boolean { 
    console.log(`Is user logged in? ' + ${this.getUser() !== null}`); 
    return this.getUser() !== null; 
    } 
} 
+0

它适合我。你能提供更多的代码吗? –

+2

打开浏览器的调试控制台(通常是大多数浏览器的F12键)。您可能在其他地方(与此无关)发生模板错误,这可能导致模板代码停止工作。 – Igor

+0

检查CSS不透明度:0;显示:无;可见性:隐藏... – Vega

回答

0

*ngIf对模型中的变化没有反应有几个可能的原因。

变化检测没有运行

您目前使用的组件OnPush战略,而无需手动触发CD周期改变组件状态。或者打开自动CD或手动触发CD,方法是注入ChangeDetectorRef并使用适合您需要的方法。

样式是在误导你

这有可能是ngIf结合工作正常并且该模板正确地创建和销毁,但也有款式在视觉上模糊的这一点,如display: nonevisibility: hidden,等确保通过打开浏览器的开发工具来检查页面。

有未被捕获的错误

容易错过,如果你没有你的控制台,同时开发开放。可能有一个错误已经破坏了你的代码,Angular无法从它恢复;从而阻止任何进一步的CD周期运行并更新DOM。一定要有一个开放的控制台来检查错误。

你甚至没有改变模型

角是一个框架,你声明指定要如何基于该模型要创建的DOM。你通过编写模板来做到这一点。如果你的模型没有改变,DOM也不会。确保正确的代码片段正在运行。一个快速的方法是将console.log置于更改变量的代码附近。您还可以在浏览器的开发工具中放置断点,或使用Chrome的实用程序扩展(如Augury)独立于基于模板渲染模型来检查模型。

+0

非常感谢,但这些观点在我的案例中似乎都不是有效的。我还通过使用断点检查了代码(之前我做过console.log()以检查变量是否真的发生了变化)。没有错误,并且我没有弄乱变化检测。我不知道我应该如何检查CSS“隐藏”等,但我的CSS基本上不存在,并且所有其他* ngIf在同一个组件上工作(尽管它们是通过表单验证而不是单个属性进行检查的) 。 – codepleb

0

我的问题是,*ngIf出现在<form></form>标签中。如果我把它放在外面,一切都奏效。我知道角使用表单标签来注入他们的表单模块,但我没有想到这样的行为。因此,我的验证错误只会在表单本身出现其他验证错误时弹出。

+0

'ngIf'没有理由不能在'form'标签中工作。 –