标签: angular2-changedetection

如何检测Angular中@Input()值何时发生变化?

我有一个父组件(CategoryComponent),一个子组件(videoListComponent)和一个ApiService.

我有大部分工作正常,即每个组件可以访问json api并通过observable获取其相关数据.

目前视频列表组件只是获取所有视频,我想将其过滤为特定类别中的视频,我通过将categoryId传递给子项来实现此目的@Input().

CategoryComponent.html

<video-list *ngIf="category" [categoryId]="category.id"></video-list>
Run Code Online (Sandbox Code Playgroud)

这有效,当父CategoryComponent类别更改时,categoryId值将通过via传递,@Input()但我需要在VideoListComponent中检测到这一点并通过APIService(使用新的categoryId)重新请求视频数组.

在AngularJS中,我会对$watch变量做一个.处理这个问题的最佳方法是什么?

angular2-changedetection angular

382
推荐指数
13
解决办法
23万
查看次数

在Angular中手动触发变化检测

我正在编写一个具有属性的Angular组件Mode(): string.我希望能够以编程方式设置此属性,而不是响应任何事件.问题是在没有浏览器事件的情况下,模板绑定{{Mode}}不会更新.有没有办法手动触发此更改检测?

angular2-changedetection angular

352
推荐指数
4
解决办法
21万
查看次数

ExpressionChangedAfterItHasBeenCheckedError解释

请向我解释为什么我一直收到这个错误: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.

显然,我只是在开发模式下获得它,它不会在我的生产版本中发生,但它非常烦人,而我根本不理解在我的开发环境中出现错误的好处 - 不会出现在prod上 - - 可能是因为我缺乏理解.

通常,修复很容易,我只是将错误导致代码包装在setTimeout中,如下所示:

setTimeout(()=> {
    this.isLoading = true;
}, 0);
Run Code Online (Sandbox Code Playgroud)

或者使用如下构造函数强制检测更改constructor(private cd: ChangeDetectorRef) {}::

this.isLoading = true;
this.cd.detectChanges();
Run Code Online (Sandbox Code Playgroud)

但为什么我经常遇到这个错误?我想了解它,以便将来可以避免这些hacky修复.

angular2-changedetection angular2-databinding angular

243
推荐指数
18
解决办法
15万
查看次数

什么是Angular相当于AngularJS $手表?

在AngularJS中,您可以使用$watch函数来指定观察者观察范围变量的变化$scope.在Angular中观察变量(例如,组件变量)的等价物是什么?

angular2-changedetection angular

204
推荐指数
7
解决办法
14万
查看次数

*ngIf中的Angular 2 @ViewChild

显示模板中相应元素后获取@ViewChild最优雅的方法是什么?以下是一个例子.也有Plunker可用.

模板:

<div id="layout" *ngIf="display">
    <div #contentPlaceholder></div>
</div>
Run Code Online (Sandbox Code Playgroud)

零件:

export class AppComponent {

    display = false;
    @ViewChild('contentPlaceholder', {read: ViewContainerRef}) viewContainerRef;

    show() {
        this.display = true;
        console.log(this.viewContainerRef); // undefined
        setTimeout(()=> {
            console.log(this.viewContainerRef); // OK
        }, 1);
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个默认隐藏其内容的组件.当有人调用@ViewChild方法时,它变得可见.但是,在角度2变化检测完成之前,我无法参考show().我通常将所有必需的操作包装成viewContainerRef如上所示.有更正确的方法吗?

我知道有一个选项setTimeout(()=>{},1),但它会导致太多无用的通话.

答案(Plunker)

angular2-changedetection angular

172
推荐指数
8
解决办法
7万
查看次数

如何强制组件在Angular 2中重新渲染?

如何强制组件在Angular 2中重新渲染?出于调试目的,使用Redux我想强制组件重新渲染它的视图,这可能吗?

angular2-changedetection angular

160
推荐指数
6
解决办法
17万
查看次数

markForCheck()和detectChanges()之间有什么区别

ChangeDetectorRef.markForCheck()和之间有什么区别ChangeDetectorRef.detectChanges()

我只在SO上找到了关于NgZone.run()这两个函数之间的差异的信息,但不是这两个函数之间的区别.

对于仅提及文档的答案,请说明一些实际场景,以选择其中一个.

angular2-changedetection angular

146
推荐指数
4
解决办法
5万
查看次数

Angular2 - 表达式在检查后发生了变化 - 使用resize事件绑定到div宽度

我已经对这个错误进行了一些阅读和调查,但不确定我的情况的正确答案是什么.我知道在开发模式下,更改检测运行两次,但我不愿意enableProdMode()用来掩盖问题.

下面是一个简单的示例,其中表格中的单元格数量应随着div的宽度扩展而增加.(请注意,div的宽度不仅仅是屏幕宽度的函数,因此不能轻易应用@Media)

我的HTML看起来如下(widget.template.html):

<div #widgetParentDiv class="Content">
<p>Sample widget</p>
<table><tr>
   <td>Value1</td>
   <td *ngIf="widgetParentDiv.clientWidth>350">Value2</td>
   <td *ngIf="widgetParentDiv.clientWidth>700">Value3</td>
</tr></table>
Run Code Online (Sandbox Code Playgroud)

这本身没有任何作用.我猜这是因为没有任何因素导致发生变化检测.但是,当我将第一行更改为以下内容并创建一个空函数来接收调用时,它开始工作,但偶尔我得到'表达式在检查后已更改错误'

<div #widgetParentDiv class="Content">
   gets replaced with
      <div #widgetParentDiv (window:resize)=parentResize(10) class="Content">
Run Code Online (Sandbox Code Playgroud)

我最好的猜测是,通过这种修改,触发更改检测并且一切都开始响应,但是,当宽度快速变化时抛出异常,因为前一次更改检测迭代需要更长的时间来完成,而不是更改div的宽度.

  1. 有没有更好的方法来触发变化检测?
  2. 我是否应该通过函数捕获resize事件以确保发生更改检测?
  3. 使用#widthParentDiv来访问可接受的div的宽度?
  4. 有更好的整体解决方案吗?

有关我的项目的更多详细信息,请参阅类似问题.

谢谢

javascript responsive-design angular2-changedetection angular

40
推荐指数
2
解决办法
6万
查看次数

从服务触发组件视图的更新 - 没有ChangeDetectorRef的提供者

我想用udpate我的应用程序视图,由服务事件触发.

我的一个服务注入了ChangeDetectorRef.编译工作正常,但是当App被引导时,我在浏览器中出现错误:No provider for ChangeDetectorRef!.

我以为我需要将它添加到我的AppModule中,但我找不到任何表明它在我可以导入的模块中的文档.我尝试将类本身添加到导入数组,但这导致了错误.尝试将其添加到模块中的providers数组时,我也遇到错误.这是我的服务的简化版本:

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

@Injectable()
export class MyService {
  private count: number = 0;
  constructor(private ref: ChangeDetectorRef){}

  increment() {
    this.count++;
    this.ref.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)

和app模块:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

import { MyService } from './my.service';

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ AppComponent ],
  providers: [ MyService ],
  booststrap: [ AppComponent ]
})
export AppModule {}
Run Code Online (Sandbox Code Playgroud)

UPDATE

我已经尝试删除我对ChangeDetectorRef的使用,但我仍然遇到同样的问题.我猜我更新了我的System …

typescript angular2-changedetection angular

40
推荐指数
2
解决办法
2万
查看次数

Angular2 zone.run()vs ChangeDetectorRef.detectChanges()

假设我function noificationHandler()在我的service.ts中有一个超出angular的上下文. noificationHandler()由第三方调用并noificationHandler()基本上使用数组并将数组发送到已订阅其服务的组件.

service.ts

    public mySubject: Subject<any> = new Subject();
    public myObservable = this.mySubject.asObservable();

    constructor() {
       this.registry.subscribe("notification.msg",this.noificationHandler.bind(this));
    }

    noificationHandler(data) {
       this.publishUpdate(data)
    }

    publishUpdate(data) {
       this.mySubject.next(data);
    }
Run Code Online (Sandbox Code Playgroud)

component.ts

constructor(private service: myService) {
    this.service.myObservable.subscribe(list => {
        this.list = list;
    });
}
Run Code Online (Sandbox Code Playgroud)

此时^^^模板未使用新数据更新

由于"notification.msg"它位于角度区域之外,因此("notification.msg")在调用此事件时不会运行角度变化检测.

现在有两种方法可以调用变化检测.

1)通过包装noificationHandler()angular的zone.run()的内部

 this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this)));
Run Code Online (Sandbox Code Playgroud)

2)通过单独要求组件检测变化

constructor(private service: myService, private ref: ChangeDetectorRef) {
    this.service.myObservable.subscribe(list => {
        this.list = list;
        this.ref.detectChanges(); // <==== manually invoking change detection
    }); …
Run Code Online (Sandbox Code Playgroud)

javascript angular2-changedetection angular

26
推荐指数
2
解决办法
9555
查看次数