代码之家  ›  专栏  ›  技术社区  ›  Shubham Verma

角度4:模型更改后视图没有更新?

  •  1
  • Shubham Verma  · 技术社区  · 8 年前

    我有两个 component 在我的应用程序IE中: HeaderComponent &安培 TestComponent 是的。在 Header组件 ,有一个方法名 设置用户数据() 是的。 我叫这个 设置用户日期() testcomponent方法 ansSubmit() 在档案里 test.component.ts 是的。

    现在 setUserDate() 正在召唤,价值正在到来 设置用户日期() 方法。

    问题是: 什么时候? 设置用户日期() 打电话来,我正在将分数值设置为 this.userdata.score网站 ,和 this.userdata.score网站 值在视图(HTML)中绑定,但来自 testcomponent的方法anssubmit()不会在视图上更新 但价值体现在 ts 文件(我正在控制台中打印)。

    代码如下:

    测试组件:

    import { HeaderComponent } from '../../components/header/header.component';
    @Component({
      selector: 'test-page',
      templateUrl: './test.component.html',
      styleUrls: ['./test.component.css'],
      providers: [HeaderComponent]
    })
    
    export class TestComponent implements OnInit {
      private userData: any = {};
    
      constructor(private _router: Router, private headerComponent: HeaderComponent) { }
    
      ansSubmit() {
        const logged_in_user = new LocalStorage(environment.localStorageKeys.ADMIN);
        this.userData = logged_in_user.value;
        this.userData['score'] = parseInt(this.userData.score) + 54321 
    
        this.headerComponent.getUserData(this.userData['score']); // Calling HeaderComponent's method  value is 54321.
      }
    }
    

    test.component.html:测试组件:

     <div class="col-2">
         <button (click)="ansSubmit()" >
              <div>Submit Answer</div>
          </button>
    </div>
    

    标题.component.ts:

    import {
      Component, OnInit, ChangeDetectorRef, NgZone, ApplicationRef, ChangeDetectionStrategy
    } from '@angular/core';
    
    
    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.css'],
    
    })
    
    export class HeaderComponent implements OnInit {
        public userData : any = {
          score:2000,
       };
    
      getUserData(score) { // score= 54321  ( value is coming )  
           this.userData.score = score ;
           console.log(this.userData.score);  // in this.userData.score = 54321  ( Value is assigning )
         } 
      }
    }
    

    header.component.html文件:

    <span class="topbar-details">
                Scrore : {{userData.score }}  // actual problem is here, Its not updating value. Its only showing 2000.
    </span>
    

    请建议我如何解决这个问题。提前谢谢。

    5 回复  |  直到 8 年前
        1
  •  3
  •   jmkelm08    7 年前

    我相信你之所以挣扎是因为你似乎有兄弟组件试图操纵数据,其中没有一个是真正的数据所有者。角度尝试强制 Unidirectional Data Flow 这仅仅意味着数据从父级流向子级,而不是从子级流向父级。解决问题的最简单方法是让“拥有”用户数据的父组件和子组件绑定到数据以显示它并发出事件来操作它。

    以您的场景为例:

    应用组件

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      public userData: any = {
        score: 2000
    };
    
     updateScore(score: number): void {
       this.userData.score += score;
     }
    }
    

    app.component.html软件

    <app-header [score]="userData.score"></app-header>
    <app-test (onScoreChange)="updateScore($event)"></app-test>
    

    标题.component.ts

    从'@angular/core'导入{component,oninit,input};

    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.css']
    })
    export class HeaderComponent implements OnInit {
      @Input('score') score: number;
    
      constructor() { }
    
      ngOnInit() {
      }
    
    }
    

    header.component.html标题

    <span class="topbar-details">
      Scrore : {{score}}
    </span>
    

    测试组件

    从“@angular/core”导入{component,oninit,output,eventemitter};

    @Component({
      selector: 'app-test',
      templateUrl: './test.component.html',
      styleUrls: ['./test.component.css']
    })
    export class TestComponent implements OnInit {
      @Output('onScoreChange') onScoreChange = new EventEmitter<number>();
    
      constructor() { }
    
      ngOnInit() {
      }
    
      ansSubmit() {
        this.onScoreChange.emit(54321);
      }
    }
    

    test.component.html测试组件

    <div class="col-2">
      <button (click)="ansSubmit()" >
        <div>Submit Answer</div>
      </button>
    </div>
    

    注: 至于从本地存储加载用户信息,我将使用一个服务来处理。加载用户数据的位置和方式并不是显示和操作数据的组件真正关心的问题。将该逻辑移动到具有适当接口的服务(如果数据可能来自远程位置,则可能返回可观察数据)将允许您无缝地将基于本地存储的服务替换为基于http的服务,以强制将所有分数传输到/从服务器发送,而不更改组件中的代码行。它还允许您交换模拟服务以进行测试,这样本地存储就不需要播种以使测试通过(即,您的测试必须对要通过的组件的实现了解得更少,这样在实现更改时它们就不会那么脆弱)

        2
  •  2
  •   thenninger    8 年前

    您正在将HeaderComponent添加为提供程序,因此它可能正在创建该组件的新实例。如果您有一个现有的headercomponent,则需要获取该实例的一个hold,因此使用服务将有助于保留对该组件实例的引用。

    最好将分数全部转移到服务中,并使用主题更新其值。查看他们的文档: https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service 是的。实际上,文档中列出的任何策略都应该对您的情况有用。

        3
  •  0
  •   Shashank Vivek    8 年前

    因为您试图从一个组件获取信息并在另一个组件中显示,所以应该使用事件。

    组件数据:

    @Output() userDataEvent = new EventEmitter<any>();
    ----
    getUserData(score?){
          this.score=score?score:this.userData.score;     
          console.log("getUserData called :"+this.score);  
          this.userDataEvent.emit(this.score);
     }
    

    显示组件:

    <your-component (userDataEvent)='setUserData($event)'></your-component>
    

    然后, setUserData 是一个函数,它向您介绍来自其他组件的数据

        4
  •  0
  •   Damodharan J    8 年前

    尝试实现对headercomponent的更改

    export class MyComponent implements OnInit, OnChanges {
     ngOnChanges(changes: SimpleChanges): void {
       // do your action
     }
    }
    

    我建议您使用角度服务或@output,并在根中发出事件,并在头中监听它们。 请看一下角反应性的基本类型。 onchanges监听器用于侦听在角度之外所做的更改(如库)。 你应该把这当作最后的手段!

        5
  •  0
  •   Hyuck Kang    7 年前

    我想问题在于 HeaderComponent 不止一个。可能是你的注射引起的

    constructor(private _router: Router, private headerComponent: HeaderComponent) { } 是的。

    请尝试下面的代码,找出导致问题的原因。

    标题.component.ts

    import {
      Component, OnInit, ChangeDetectorRef, NgZone, ApplicationRef, ChangeDetectionStrategy
    } from '@angular/core';
    
    
    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.css'],
    
    })
    
    export class HeaderComponent implements OnInit {
        static count:number = 0;
        public id:number = 0;
        public userData : any = {
          score:2000,
        };
    
        constructor(){
          HeaderComponent.count++;
          this.id = HeaderComponent.count
        }
    
        getUserData(score) { // score= 54321  ( value is coming )  
           this.userData.score = score ;
           console.log(`${this._id} : ${this.userData.score}`);  // in this.userData.score = 54321  ( Value is assigning )
        } 
      }
    }
    

    header.component.html标题

    <span>id : {{id}}</span>
    <span class="topbar-details">
       Scrore : {{userData.score }}  // actual problem is here, Its not updating value. Its only showing 2000.
    </span>
    

    如果 身份证件 在视野中 身份证件 在控制台中是不同的,这意味着您没有更新 Header组件 视图中的实例,但另一个 Header组件 在控制台中打印日志的实例。

    请试试这个告诉我结果。谢谢您。

    推荐文章