我有一个父组件(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变量做一个.处理这个问题的最佳方法是什么?
我正在编写一个具有属性的Angular组件Mode(): string.我希望能够以编程方式设置此属性,而不是响应任何事件.问题是在没有浏览器事件的情况下,模板绑定{{Mode}}不会更新.有没有办法手动触发此更改检测?
请向我解释为什么我一直收到这个错误: 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修复.
在AngularJS中,您可以使用$watch函数来指定观察者观察范围变量的变化$scope.在Angular中观察变量(例如,组件变量)的等价物是什么?
显示模板中相应元素后获取@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),但它会导致太多无用的通话.
如何强制组件在Angular 2中重新渲染?出于调试目的,使用Redux我想强制组件重新渲染它的视图,这可能吗?
ChangeDetectorRef.markForCheck()和之间有什么区别ChangeDetectorRef.detectChanges()?
我只在SO上找到了关于NgZone.run()这两个函数之间的差异的信息,但不是这两个函数之间的区别.
对于仅提及文档的答案,请说明一些实际场景,以选择其中一个.
我已经对这个错误进行了一些阅读和调查,但不确定我的情况的正确答案是什么.我知道在开发模式下,更改检测运行两次,但我不愿意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的宽度.
有关我的项目的更多详细信息,请参阅此类似问题.
谢谢
javascript responsive-design angular2-changedetection angular
我想用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 …
假设我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)