标签: angular-changedetection

store.select subscribe 中的更改检测需要 markForCheck。为什么?

我的应用程序组件正在订阅商店选择。我设置ChangeDetectionStrategyOnPush. 我一直在阅读有关这是如何工作的;需要更新对象引用才能触发更改。然而,当您使用异步管道时,Angular 会期待新的可观察更改并为您执行 MarkForCheck。MarkForCheck那么,当触发订阅并设置channels$新的可观察通道数组时,为什么我的代码不渲染通道(除非我调用)。

@Component({
  selector: 'podcast-search',
  changeDetection: ChangeDetectionStrategy.OnPush, // turn this off if you want everything handled by NGRX. No watches. NgModel wont work
  template: `
    <h1>Podcasts Search</h1>
    <div>
      <input name="searchValue" type="text" [(ngModel)]="searchValue" ><button type="submit" (click)="doSearch()">Search</button>
    </div>
    <hr>
    <div *ngIf="showChannels">

      <h2>Found the following channels</h2>
      <div *ngFor="let channel of channels$ | async" (click)="loadChannel( channel )">{{channel.trackName}}</div>
    </div>
  `,
})

export class PodcastSearchComponent implements OnInit {
  channels$: Observable<Channel[]>;
  searchValue: string;
  showChannels = false;
  test: …
Run Code Online (Sandbox Code Playgroud)

ngrx angular angular-changedetection

6
推荐指数
1
解决办法
4692
查看次数

在Angular中渲染基于时间的Observable,而不会出现压倒性的变化检测

我们的Angular应用程序中有许多组件需要定期显示每个组件唯一的新值(倒计时,时间戳,已用时间等).最自然的方法是创建使用RxJS timerinterval工厂函数的observable .但是,这些会在调用间隔函数时多次触发整个应用程序的每个间隔的角度变化检测.如果我们在页面上有许多组件,则会触发每秒或每个时间段对整个应用程序进行数十次检测,从而产生很大的性能开销.

到目前为止,我有两种尝试解决问题的方法.对这两者的一个好的答案将是非常有帮助的 - 理想的是两者.我想避免手动触发变化检测,而是依赖于Observables发出的新值,并让异步管道/ OnPush变化检测策略负责触发变化检测.如果这是不可能的,我想了解原因.

  1. 有没有办法禁用或阻止RxJS timerinterval函数触发角度变化检测?使用NgZone zone.runOutsideAngular(() => this.interval$ = interval(1000) ... )似乎不会这样做.StackBlitz示例:https://stackblitz.com/edit/angular-zo5h39
  2. 或者,如果我使用RxJS Subject结合setInterval被调用的内部创建一个Observable流zone.runOutsideAngular,为什么在从主题发出新值时不会为子组件触发更改检测?StackBlitz示例:https://stackblitz.com/edit/angular-yxdjgd

javascript rxjs angular angular-changedetection

6
推荐指数
1
解决办法
505
查看次数

表单组值更改时不会触发更改检测

我创建了一个简单的示例来演示我面临的一个奇怪问题。

Stackblitz- https: //stackblitz.com/edit/angular-change-detection-form-group

我有三个组成部分,它们是:

1-应用程序组件

import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `<hello [form]="form"></hello>
  <hr />
  <button (click)="changeFormValue()">Change Form Value</button>`,
  styleUrls: ['./app.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush

})
export class AppComponent implements OnInit {
  name = 'Angular';

  form: FormGroup;

  ngOnInit() {
    this.form = new FormGroup({
      name: new FormControl('ABC'),
      age: new FormControl('24')
    });
  }

  changeFormValue() {
    this.form.setValue({
      name: 'XYZ',
      age: 35
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

2-Hello组件

import { Component, Input, OnChanges, ChangeDetectionStrategy …
Run Code Online (Sandbox Code Playgroud)

angular angular-changedetection

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

有角。为什么调用markForCheck()结果来查看更新

到处都说 markForCheck 只是将当前组件视图和所有父组件(直到根组件)标记为脏组件。因此下次执行 DetectChanges 时它将更新视图。从这一点上我有两个问题。两者都在该组件具有的上下文中changeDetection: ChangeDetectionStrategy.OnPush

1)如果“async pipeline”除了调用markForCheck(源代码)什么都不做,为什么视图会更新?

2)如果我尝试在某个异步进程中调用markForCheck,视图也会更新。

演示:stackblitz

您能帮助我了解这些过程中发生的情况以及视图实际更新的原因吗?我期待有人在 1) 和 2) 之后调用 DetectChanges 方法,但是谁......

angular angular-changedetection

6
推荐指数
1
解决办法
3904
查看次数

我是否应该始终使用ChangeDetectionStrategy.OnPush

我应该始终ChangeDetectionStrategy.OnPush在组件中使用吗?

我总是听到OnPush它绝对令人惊讶,并解决了许多问题,加快了Angular应用的速度,甚至摆脱了NgZone。但是,如果是这样,为什么默认情况下不生成它ng g component

如果真是太神奇了,那我们应该一直使用它吗?

angular2-changedetection angular angular-changedetection

5
推荐指数
2
解决办法
517
查看次数

当我从 ChangeDetectorRef 调用 detach() 时,为什么会调用 ngDoCheck() ?

我正在阅读一些有关更改检测的文章,并且尝试使用 和 启用或禁用更改changeDetectorRef.detach()检测changeDetectorRef.reattach()

我还将该组件挂接到唯一ngDoCheck()发现ngDoCheck()即使在之后也被调用detach()。我究竟做错了什么 ?有人可以解释为什么ngDocheck()被称为吗?我什至也有ChangeDetectionStartegy设置OnPush这是我正在阅读的文章以了解变更检测

我还为此创建了一个示例:https ://stackblitz.com/edit/angular-4ytdbs

observable angular angular-changedetection

5
推荐指数
1
解决办法
687
查看次数

Angular7-两次键入相同的值时,[ngModel]不会在组件中更新

最小的Stackblitz示例

https://stackblitz.com/edit/angular-mqqvz1

在Angular 7 App中,我创建了一个带有<input>字段的简单组件。

当我使用键盘更改输入值时,我希望该值的格式设置为onBlur。-在最小的示例中,我只想向其中添加字符串“ EDIT”

这基本上是有效的:

  • 如果我输入“ test”并模糊该字段,它将更改为“ test EDIT”
  • 如果我输入“ lala”并模糊该字段,它将更改为“ lala EDIT”

但是, 当我键入“测试”-模糊(有效)并再次键入“测试”时,它将不再起作用!

onInputUpdate()功能全被调用(你可以看到它在控制台日志),变量inputValue被更新(你可以看到它的组件{{inputValue}}),但是输入值不会改变! 我希望它是“测试编辑”,但它保持“测试”。

当我键入另一个字符串时,它可以工作,但是连续两次在同一字符串中输入却不起作用。这是为什么?我怎样才能解决这个问题?

component.html

{{inputValue}} <br />
<input type="text"
       [ngModel]="inputValue"
       (ngModelChange)="onInputUpdate($event)"
       [ngModelOptions]="{ updateOn: 'blur' }"/>
Run Code Online (Sandbox Code Playgroud)

component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {

  inputValue = "teststring";

  constructor(
    private changeDetectorRef: ChangeDetectorRef,
  ) {}

  public ngOnInit() {
    this.inputValue = "initial";
  }

  public onInputUpdate(inputValue: string) …
Run Code Online (Sandbox Code Playgroud)

angular-ngmodel angular-components angular angular-changedetection angular7

5
推荐指数
1
解决办法
2607
查看次数

从 ngOnChanges 更改组件输入,同时使用 OnPush 策略

我在使用 Angular 6 应用程序时遇到问题:

问题

假设我有 2 个组件:父组件和子组件。

孩子有2个输入。当 1 个输入发生变化时,在 ngOnChanges() 中,子组件向父组件发出一些东西。

然后父组件更改子组件的第二个输入。我希望再次调用子组件的更改检测 - 但事实并非如此。子组件的视图显示了第二个输入的旧值。


辩解

该申请有以下定义:

  1. 所有组件都使用变更检测策略 OnPush。包括根组件。
  2. 我正在使用 ngrx 商店。在减速器中调用 markForCheck() 或 detectChanges() 不是一个选项。
  3. 数据使用异步管道向下传输到子组件,因为它来自使用选择器(可观察)的存储。
  4. 我不能更早地导致第二个输入的更改(例如在父组件中)-它必须在子组件接收到第一个输入的更改之后发生。

为了说明这个案例,我创建了一个简单的演示项目。在那里我不使用商店,所以我没有任何选择器......相反,我使用 rxjs Subject 来使用异步管道。

这里是:

https://angular-ccejq4.stackblitz.io

查看控制台以了解会发生什么以及何时发生。


糟糕的解决方案

我已经尝试过的:

  1. 将根组件的更改检测策略更改为默认值。它有效,但这不是一个好的解决方案,因为它会导致性能问题。
  2. 在发出(!)之前和之后调用 markForCheck() - 不工作。
  3. 在发出(!)之前和之后调用detectchanges() - 不工作。
  4. 在父组件订阅选择器而不是使用异步管道 - 不工作。
  5. 从 setTimeout 中调用发射 - 它有效。但有更好的解决方案吗?一个更 Angular 驱动的。因为这个解决方案更像是一种解决方法。
  6. 使用 ngAfterViewInit/ngAfterViewChecked 并发出,从那里调用 markForCheck() 和 detectChanges() - 不工作。

我发现新值到达异步管道。然后异步管道调用 markForCheck()。但它不会调用detectChanges()..所以更改检测周期不会运行。视图只会在下一个更改检测周期时正确更改 - 正如您在我的演示应用程序中看到的那样。


有任何想法吗?

谢谢!

rxjs ngrx angular2-changedetection angular angular-changedetection

5
推荐指数
1
解决办法
602
查看次数

我在 Angular 的更改检测中的断点未在 checkAndUpdateView() 上触发

对角的变化检测好文章,我想调试checkAndUpdateView功能。但是,它永远不会被触发。

在此处输入图片说明

我错过了什么?我尝试使用最新的 Chrome 和 Firefox。

angular angular-changedetection

5
推荐指数
1
解决办法
273
查看次数

为什么 Angular 异步管道使用 cdr.markForCheck() 而不是 cdr.detectChanges()?

我有一个一般性的角度问题:

为什么async使用角管cdr.markForCheck()而不是cdr.detectChanges()

我认为这两种“风格”有两个主要区别:

  1. markForCheck()标记要检查的路径直到根组件 -要更新的内容
  2. markForCheck()让变化检测发生在当前或下一个周期 -计时

我的想法或问题:

  1. 为什么我们需要检查根的整个路径(在async管道中)?为什么不只是当前组件?( ) - 这与要更新的内容detectChanges()有关

  2. 为什么只标记(对于当前/下一个周期 - 使用markForCheck()ngZone)?为什么不立即检测变化?( ) 这与时间detectChanges()有关

  3. 如果没有 ngZone 异步触发器/没有异步操作怎么办?那么视图更新不会发生吗?

  4. async如果我们改为使用管道会发生什么detectChanges()


异步管道

  private _updateLatestValue(async: any, value: Object): void {
    if (async === this._obj) {
      this._latestValue = value;
      this._ref.markForCheck();
    }
  }
Run Code Online (Sandbox Code Playgroud)

编辑:

async请不要解释每种方法的作用,因为我在文档中阅读了很多次,并且从角度来看我无法理解。对我来说,重要的是要知道更新内容时间安排的原因。

angular ngzone angular-changedetection angular-ngzone

5
推荐指数
1
解决办法
2032
查看次数