为什么我的观点没有更新?

时间:2017-02-14 12:35:06

标签: angular

在下面的代码中,正如您所看到的,我订阅了一个observable,在回调中我将状态设置为result的值。这用于视图上的* ngIf。事实是,即使返回true,视图也不会更新。

  export class AppComponent {

  private status;

  constructor (private proxyService: ProxyService) {

  }

  ngOnInit(){
    //setInterval(()=>console.log(this.isInjected),1000);
    this.proxyService.someObservable.subscribe((result)=>{
      this.status = result;
      console.log(result);
    });
  }

}

现在,您可能会注意到注释行。调试时我添加了它,奇怪的是它使视图更新。有什么想法吗?

供参考,这是我的观点:

  <div *ngIf="status">
    <app-userlane-inject></app-userlane-inject>
  </div>
  <div *ngIf="!status">
    <span>Status is false.</span>
  </div>
{{status}}

永远不会渲染子组件,即使控制台记录为true,字符串插值仍然为false(除非间隔存在,否则它可以工作)。

以下是该服务的广义内容:

var mySubject= new BehaviorSubject(false);


@Injectable()
export class ProxyService {
  public someObservable= mySubject.asObservable();


//Kinda deep callback tree, then finally
  mySubject.next(true)

}

将答案放入上下文中的一些额外信息:我上面提到的深度回调链完全脱离了角度(这是一个扩展,并且调用链包括向内容脚本发送消息,然后发送到页面,以及一直回来)。 这就是角度区域需要再次被调用的原因。 我不知道那是什么原因,这就是为什么我在最初的问题上没有包含这个原因。

2 个答案:

答案 0 :(得分:2)

我认为如果你在课堂外初始化mySubject,它将在Angulars区域外运行,这将阻止Angular识别事件,因此不会运行变化检测。

@Injectable()
export class ProxyService {
  private mySubject= new BehaviorSubject(false);
  public someObservable= this.mySubject.asObservable();


//Kinda deep callback tree, then finally
  this.mySubject.next(true)
}

<强>更新

您可以使用

  constructor(private zone:NgZone) {}
  this.zone.run(()=> this.mySubject.next(true));

但是如果这解决了你的问题,那么调用链中可能出现了一些错误,其中一些事件或回调没有发生在Angulars区域内。

答案 1 :(得分:0)

显示可观察对象的最佳方法是创建一个哑组件来显示它们。

示例:

如果this.status是可观察的

创建一个哑组件来显示它。

//dumb component to display status

   @Component({
      selector: 'dumb-display-comp',
      template: '{{ status }}'  
    })
    export class DumbDisplayComp {
        @Input() status: any;
    }

现在在父组件中使用哑组件,并使用异步管道将observable作为输入发送。

使用哑组件的父模板

<dumb-display-comp [status]="status | async" ></dumb-display-comp>

你的应用程序应该填充愚蠢的组件来整理你的主要组件。 只是我的两分钱。