2017-09-24 102 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'標籤中工作。 –