模型更新,但即使使用Ngzone,Angular Ui也不会重新渲染 [英] Model updates but Angular Ui does not Rerender even with Ngzone

查看:44
本文介绍了模型更新,但即使使用Ngzone,Angular Ui也不会重新渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要求,即从Angular外部的外部输入字段中获取输入值,使用该值触发Angular模块中的服务,该服务从后端获取相关数据.订阅功能可以很好地进行内部更改,但是由于此处的输入值来自全局函数,因此不会呈现UI.

I have a requirement where from an external input field outside Angular I am getting input values, using which I am triggering a service in my Angular module which gets relevant data from the back-end. Subscribe function is working fine for internal changes but since here the input values are coming from global function, the UI is not getting rendered.

我尝试了 zone.run detectChange detectCheck ,但是似乎没有任何东西可以更新UI.UI应该使用 suggestedItems 数组显示项目列表.请让我知道怎么了.

I have tried zone.run, detectChange, and detectCheck but nothing seems to be updating the UI. The UI is supposed to display the list of items using the suggestedItems array. Please let me know what's wrong.

    import { Component, OnInit, HostListener, NgZone, ChangeDetectorRef } from '@angular/core';
    import { BackendApiService } from '../services/backend-api.service';
    import { WindowAccessService } from '../services/window-access.service';
    @Component({
      selector: 'app-search-suggestion',
      templateUrl: './search-suggestion.component.html',
      styleUrls: ['./search-suggestion.component.scss']
    })
    export class SearchSuggestionComponent implements OnInit {
      suggestionHeaders = ['Item', 'Item name', 'Item category', 'Item details'];
      suggestedItems; dummyRequestObj; value;

      calledFromOutside(newValue: String) {
        this.zone.run(() => {
        this.value = newValue;
        this.dummyRequestObj.conditions = [];
        this.dummyRequestObj.conditions.push({
                        'column': 'SEARCH_BY_NAME',
                        'value': this.value
                        });
          // this.chngDt.detectChanges();
        this.items.getData(this.dummyRequestObj, false, false);
        console.log(this.value);
      });
      }
      // tslint:disable-next-line:max-line-length
      constructor( public items: BackendApiService, private zone: NgZone, public refWin: WindowAccessService, private chngDt: ChangeDetectorRef) {
        this.suggestedItems = new Array<any>();
    }
    ngOnInit() {
        this.items.updateItemList.subscribe(
          (data) => {
            console.log('was triggered');
            this.zone.run(() => {
            this.suggestedItems = data;
            });
            // this.chngDt.markForCheck();
            console.log('data', this.suggestedItems);
          }
        );
        this.refWin.nativeWindow.angularComponentRef = {
          zone: this.zone,
          componentFn: (value) => this.calledFromOutside(value),
          component: this
        };
        this.dummyRequestObj = {
                    "preciseSearch": false,
                    "useFuzzy": false,
                    "mode": 0,
                    "startIndex": 0,
                    "noOfRecords": 12,
                    "ascending": false
    };
    }
<div class="table-responsive">
    <table class="table table-hover">
        <thead>
            <tr>
                <th  *ngFor="let header of suggestionHeaders">{{header}</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let item of suggestedItems">
                <td>{{item.erpPartNumber}}</td>
                <td>{{item.itemShortDesc}}</td>
                <td>{{item.productCategoryName}}</td>
                <td>{{item.itemDesc}}</td>
           </tr>
        </tbody>
    </table>
</div>

推荐答案

请在适当的console.logging中添加一个ngOnChanges()块,以记录您对更改有兴趣的变量.我们可以去那里.您最有可能会发现:

Please add an ngOnChanges() block with the appropriate console.logging for the variable you are interested reacting to changes on. We can go for there. Most likely you will find:

  • 该变量未更新
  • 该变量将重置为默认状态
  • 或者,变更检测策略未按您期望的那样设置

您需要将钩子添加到类定义中,以便OnChanges能够正确触发:

You will need to add the hook to your class definition for OnChanges to fire properly:

export class SearchSuggestionComponent implements OnInit, OnChanges {

更新:我将您的代码添加到了plunkr中,并模拟了您的服务电话.如果将填充了uggestedItems的代码移到ngOnInit中,看来您可能会遇到更好的运气.

Update: I added your code to a plunkr and mocked out your service call. It seems you may have better luck if you move the code that populates suggestedItems into your ngOnInit:

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

@Component({
  selector: 'app-root',
  template: `
    <div class="table-responsive">
      <table class="table table-hover">
        <thead>
        <tr>
          <th *ngFor="let header of suggestionHeaders">{{header}}</th>
        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let item of suggestedItems">
          <td>{{item.erpPartNumber}}</td>
          <td>{{item.itemShortDesc}}</td>
          <td>{{item.productCategoryName}}</td>
          <td>{{item.itemDesc}}</td>
        </tr>
        </tbody>
      </table>
    </div>`
})
export class AppComponent implements OnInit {
  suggestionHeaders = ['Item', 'Item name', 'Item category', 'Item details'];
  suggestedItems; dummyRequestObj; dummyResponseObj; value; items;

  // tslint:disable-next-line:max-line-length
  constructor( ) {
    this.suggestedItems = new Array<any>();
  }
  ngOnInit() {
    this.dummyResponseObj =  [ {'erpPartNumber': 'dadd', 'itemShortDesc': 'Mobile', 'itemDesc': 'LG Mobile',
      'productCategoryCode': '42', 'productCategoryName': 'Prisoners defense services', 'uom': 'EA'},
      {'erpPartNumber': 'data 2', 'itemShortDesc': 'Mobile', 'itemDesc': 'LG Mobile',
        'productCategoryCode': '323', 'productCategoryName': 'Prisoners defense services', 'uom': 'EA'}];

    this.items = this.dummyResponseObj;
    this.suggestedItems = this.dummyResponseObj;
         }
}

基本上,您尝试过早混合此变量.您需要在OnInit中更新对象,以确保Angular准备就绪,模板已及时绑定到组件代码,并且更改检测可操作.很多时候在ngOnInit之前完成的工作会导致模板问题,因为Angular尚未完全启动.

Basically you are trying to hydrate this variable too soon. You need to update the object in OnInit to ensure Angular is ready to go, the template gets bound in time to the component code, and change detection is operational. Many times work done prior to ngOnInit will cause template issues as Angular is not fully spun up yet.

希望这会有所帮助!欢呼

这篇关于模型更新,但即使使用Ngzone,Angular Ui也不会重新渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆