2017-09-24 3 views
0

Voici quelques morceaux de code. Ce même modèle (afaik) fonctionne pour le tutoriel de héros.* ngIf ne réagit pas aux changements booléens

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! 
     } 
     } 

Le message ne soit pas affiché, même si je mets wrongCredentialsInserted à true. Cela devient vrai, j'ai déjà validé ça. J'ai aussi essayé des choses comme *ngIf="wrongCredentialsInserted === true", parce que j'ai lu ça ailleurs, mais ça n'a pas marché. J'ai lu que cela pourrait être lié à "flux de données à sens unique, en commençant par Angular 2", mais je sais que nous avons été en mesure de faire de telles choses dans les projets A2 + dans notre société. AFAIK la liaison de données à sens unique se réfère uniquement à la communication composant-composant.

Toute forme d'aide est fortement appréciée.

EDIT: Comme il semble y avoir un peu de confusion avec les choses que j'ai faites, je poste les fichiers entiers ici.

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: Vide

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

Cela fonctionne pour moi. pouvez-vous fournir plus de code? –

+2

Ouvrez la console de débogage de votre navigateur (généralement la touche F12 dans la plupart des navigateurs). Vous avez probablement une erreur de modèle ailleurs (sans rapport avec cela) qui peut empêcher le code du template de fonctionner. – Igor

+0

Vérifiez css pour l'opacité: 0; affichage: aucun; visibility: hidden ... – Vega

Répondre

0

Il existe plusieurs raisons possibles pour *ngIf de ne pas réagir aux modifications du modèle.

La détection de changement ne fonctionne pas

Vous utilisez la stratégie OnPush sur votre composant et changer l'état composant sans déclencher manuellement un cycle de CD. Vous pouvez soit retourner le CD automatique, soit déclencher le CD manuellement en injectant le ChangeDetectorRef et en utilisant la méthode qui vous convient.

styles vous induire en erreur

Il est possible que ngIf la liaison fonctionne correctement et que le modèle est correctement créé et détruit, mais il y a des styles qui cette visuellement obscure, comme display: none, visibility: hidden, etc. Assurez-vous de inspectez la page en ouvrant les outils de développement de votre navigateur.

Il y avait une erreur non interceptée

Facile à manquer si vous ne possédez pas votre console ouverte tout en développant. Il y a peut-être eu une erreur qui a brisé votre code et Angular ne peut pas s'en remettre; empêchant ainsi d'autres cycles de CD de s'exécuter et de mettre à jour le DOM. Assurez-vous d'avoir une console ouverte pour vérifier les erreurs.

Vous n'êtes même pas changer le modèle

angulaire est un cadre dans lequel vous spécifiez déclarative comment vous voulez que le DOM à créer en fonction du modèle. Vous faites cela en écrivant des modèles. Si votre modèle ne change pas, le DOM ne le fera pas non plus. Assurez-vous que le bon morceau de code est en cours d'exécution. Un moyen rapide de le faire est de placer un console.log près du code qui change la variable. Vous pouvez également placer un point d'arrêt dans les outils de développement de votre navigateur ou utiliser une extension d'utilitaire pour Chrome, telle que Augury, pour inspecter le modèle indépendamment de la manière dont il est rendu en fonction du modèle.

+0

Merci beaucoup, mais aucun de ces points ne semble être valide dans mon cas. J'ai également vérifié le code en utilisant des points d'arrêt (j'ai fait console.log() avant de vérifier si la variable change vraiment). Pas d'erreurs, et je n'ai pas joué avec la détection de changement.Je ne sais pas exactement comment je devrais vérifier le CSS pour "caché", etc, mais mon CSS est fondamentalement inexistant et tous les autres * ngIf sur le même composant fonctionnent (bien qu'ils soient vérifiés au-dessus des validations de forme et pas des attributs simples) . – codepleb

0

Le problème dans mon cas était, que le *ngIf est apparu dans une étiquette <form></form>. Si je l'ai placé dehors, tout a fonctionné. Je sais que angulaire utilise les tags de formulaire pour injecter leur module de forme, mais je ne m'attendais pas à un tel comportement. Mon erreur de validation n'est donc apparue que lorsque le formulaire lui-même comportait d'autres erreurs de validation.

+0

Il n'y a aucune raison pour que 'ngIf' ne fonctionne pas dans une balise' form'. –