首页 文章

Angular 2组件属性更改时更新DOM

提问于
浏览
0

刚刚从Angular 1迁移到Angular 4,并且在更新组件属性时理解DOM未更新的原因有点困难 . 我搜索和阅读了无数的帖子,找不到任何似乎回答这个问题的内容 .

我有一个应用程序,它有一个用于显示错误消息的组件,名为MessageComponent:

import { Component, OnInit } from '@angular/core';                                                                   

 @Component({                                                                                                               
   selector: 'message',                                                                                                     
   templateUrl: './message.component.html',                                                                                 
   styleUrls: ['./message.component.css']                                                                                   
 })                                                                                                                         

export class MessageComponent implements OnInit {                                                                          

  messages: Array<string>;                                                                                                 

  constructor() {                                                                                                          

  }                                                                                                                        

  ngOnInit() {                                                                                                             
    this.messages = ['My messages'];                                                                                       
  }                                                                                                                        

  /* Takes an array of messages */                                                                                         

  showErrors(errors) {                                                                                                     
    this.messages = errors;                                                                                                
  }
}

模板很简单:

<div class="message">                                                                                                      
  <p>Messages go here</p>                                                                                                  
  <div class="error">                                                                                                      
     <ul>                                                                                                                 
       <li *ngFor="let message of messages">{{message}}</li>                                                              
     </ul>                                                                                                                
  </div>                                                                                                                   
</div>

我从另一个组件调用 showErrors 方法:

import { Component, OnInit } from '@angular/core';                                                                         

  import { MessageComponent } from  '../message/message.component';                                                          

  @Component({                                                                                                               
    selector: 'app-signup',                                                                                                  
    templateUrl: './signup.component.html',                                                                                  
    styleUrls: ['./signup.component.css']                                                                                    
  })                                                                                                                         
  export class SignupComponent implements OnInit {                                                                           

    email: string;                                                                                                           
    password: string;                                                                                                        
    cardNumber: string;                                                                                                      
    expiryMonth: string;                                                                                                     
    expiryYear: string;                                                                                                      
    cvc: string;                                                                                                             
    plan: string;                                                                                                            

    constructor(private activatedRoute: ActivatedRoute, private auth: Auth, private message: MessageComponent) { }           

    signupUser() {                                                                                                           
      // do stuff here, then call back with status                                                                                                                                                                                   
      }, (status: number, response: any) => {                                                                                
        if (status == 200) {                                                                                                 
          // yay, do success stuff                                                                                                
        } else {                                                                                                             
          console.log('Error', response.error.message);                                                                      
          this.message.showErrors([response.error.message]);                                                                 
        }                                                                                                                    
      });                                                                                                                    
    }

从这个表单调用 signupUser() 方法,它是 signup.component.html ,SignupComponent的模板:

<message></message>                                                                                                      
<h1>Signup</h1>                                                                                                          
<form (submit)="signupUser()">                                                                                           
  <div class="row">                                                                                                      
    <div class="small-12 columns">                                                                                       
      <label>Email address                                                                                               
          <input type="text" [(ngModel)]="email" name="email">                                                           
      </label>                                                                                                           
    </div>                                                                                                               
  </div>                                                                                                                 
  <div class="row">                                                                                                      
    <div class="small-12 columns">                                                                                       
      <label>Password                                                                                                    
        <input type="password" [(ngModel)]="password" name="password">                                                   
      </label>                                                                                                           
    </div>                                                                                                               
  </div>                                                                                                                 
  <div class="row">                                                                                                      
    <div class="small-12 columns">                                                                                       
      <label>Card Number                                                                                                 
          <input type="text" [(ngModel)]="cardNumber" name="card-number" data-stripe="number">                           
      </label>                                                                                                           
    </div>                                                                                                               
  </div>                                                                                                                 
  <div class="row">                                                                                                      
    <div class="small-6 columns">                                                                                        
      <label>Expiration Date (MM/YY)                                                                                     
        <span><input type="text" size="2" [(ngModel)]="expiryMonth" name="expiry-month" placeholder="MM"><input type="text" size="2" [(ngModel)]="expiryYear" name="expiry-year" placeholder="YY"></span>                                                      
      </label>                                                                                                           
    </div>                                                                                                               
    <div class="small-6 columns">                                                                                        
      <label>CVC                                                                                                        
        <input type="text" [(ngModel)]="cvc" name="cvc">                                                                
      </label>                                                                                                          
    </div>                                                                                                              
  </div>                                                                                                                
  <input type="submit" value="Sign Up">                                                                                 
</form>

希望's enough to get the gist. What I'能够观察到 MessagesComponent 内部的 this.messages 确实在调用时更改为正确的值,但是,DOM不会更新 .

我在这里想念的是什么?我觉得我对Angular如何检测组件属性的变化并将其传播到DOM有一些基本的误解,但我不知道它是什么我错过了 .

谢谢你的帮助!

2 回答

  • 0

    我会重新安排代码如下 . 整个想法是MessageComponent有一个Input属性,用于接收它必须显示的消息,SignupComponent使用模板绑定sintax将错误消息传递给MessageComponent .

    MessageComponent

    import { Component, OnInit, Input } from '@angular/core';                                                                   
    
     @Component({                                                                                                               
       selector: 'message',                                                                                                     
       templateUrl: './message.component.html',                                                                                 
       styleUrls: ['./message.component.css']                                                                                   
     })                                                                                                                         
    
    export class MessageComponent implements OnInit {                                                                          
    
      @Input() messages: Array<string>; // Input property                                                                                                
    
      constructor() {                                                                                                          
      }                                                                                                                        
    
      ngOnInit() {                                                                                                                                                                                                    
      }  
    }
    

    SignupComponent

    import { Component, OnInit } from '@angular/core';                                                                         
    
      @Component({                                                                                                               
        selector: 'app-signup',                                                                                                  
        templateUrl: './signup.component.html',                                                                                  
        styleUrls: ['./signup.component.css']                                                                                    
      })                                                                                                                         
      export class SignupComponent implements OnInit {                                                                           
    
        email: string;                                                                                                           
        password: string;                                                                                                        
        cardNumber: string;                                                                                                      
        expiryMonth: string;                                                                                                     
        expiryYear: string;                                                                                                      
        cvc: string;                                                                                                             
        plan: string; 
    
        messages: Array<string>;  // property used to pass the messages to the MessageComponent                                                                                                         
    
        constructor(private activatedRoute: ActivatedRoute, private auth: Auth) { }           
    
        signupUser() {                                                                                                           
          // do stuff here, then call back with status                                                                                                                                                                                   
          }, (status: number, response: any) => {                                                                                
            if (status == 200) {                                                                                                 
              // yay, do success stuff                                                                                                
            } else {                                                                                                             
              console.log('Error', response.error.message);                                                                      
              this.messages = [response.error.message];                                                                 
            }                                                                                                                    
          });                                                                                                                    
        }
    

    SignupComponent template

    <!-- TEMPLATE BINDING -->
    <message [messages]="messages"></message>                                                                                                      
    <h1>Signup</h1>                                                                                                          
    <form (submit)="signupUser()">   
    ..... the rest of your code
    </form>
    
  • 0

    我今天遇到了这个问题,我这样解决了:

    import { ChangeDetectorRef } from '@angular/core';
    

    ......它会每隔一秒通知一次变化

    constructor(private ref: ChangeDetectorRef){
    
         setInterval(() => {
           this.ref.detectChanges()
         }, 1000);
    
     }
    

    ...如果您只是通知那些,您需要在需要之后使用此行

    this.ref.detectChanges()
    

相关问题