请向我解释为什么我一直收到这个错误: 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修复.
我知道我不是第一个问这个的人,但我在前面的问题中找不到答案.我有一个组件
<div class="col-sm-5">
<laps
[lapsData]="rawLapsData"
[selectedTps]="selectedTps"
(lapsHandler)="lapsHandler($event)">
</laps>
</div>
<map
[lapsData]="rawLapsData"
class="col-sm-7">
</map>
Run Code Online (Sandbox Code Playgroud)
在控制器中rawLapsdata不时变异.
在laps,数据以表格格式输出为HTML.每当rawLapsdata发生变化时,这都
我的map组件需要ngOnChanges用作在Google地图上重绘标记的触发器.问题是当rawLapsData父项中的更改时,ngOnChanges不会触发.我能做什么?
import {Component, Input, OnInit, OnChanges, SimpleChange} from 'angular2/core';
@Component({
selector: 'map',
templateUrl: './components/edMap/edMap.html',
styleUrls: ['./components/edMap/edMap.css']
})
export class MapCmp implements OnInit, OnChanges {
@Input() lapsData: any;
map: google.maps.Map;
ngOnInit() {
...
}
ngOnChanges(changes: { [propName: string]: SimpleChange }) {
console.log('ngOnChanges = ', changes['lapsData']);
if (this.map) this.drawMarkers();
}
Run Code Online (Sandbox Code Playgroud)
更新: ngOnChanges不起作用,但看起来好像正在更新lapsData.在ngInit中,还有一个用于缩放更改的事件侦听器,它也会调用this.drawmarkers.当我改变变焦时,我确实看到了标记的变化.所以唯一的问题是我在输入数据发生变化时没有收到通知.
在父母,我有这条线.(回想一下,变化反映在圈数中,但不反映在地图中). …
我有一个父组件,它使用ajax请求检索对象数组.
该组件有两个子组件:其中一个组件以树形结构显示对象,另一个组件以表格格式呈现其内容.父级通过@input属性将数组传递给子级,并且它们正确显示内容.一切都如预期的那样.
更改对象中的某个字段时会发生此问题:子组件未通知这些更改.只有在手动将数组重新分配给其变量时才会触发更改.
我习惯使用Knockout JS,我需要获得类似于observableArrays的效果.
我读过一些关于DoCheck的内容,但我不确定它是如何工作的.
我知道在stackoverflow中已经发布了很多相同的问题并尝试了不同的解决方案以避免运行时错误,但它们都不适用于我.
组件和Html代码
export class TestComponent implements OnInit, AfterContentChecked {
@Input() DataContext: any;
@Input() Position: any;
sampleViewModel: ISampleViewModel = { DataContext: : null, Position: null };
constructor(private validationService: IValidationService, private modalService: NgbModal, private cdRef: ChangeDetectorRef) {
}
ngOnInit() {
}
ngAfterContentChecked() {
debugger;
this.sampleViewModel.DataContext = this.DataContext;
this.sampleViewModel.Position = this.Position;
}
<div class="container-fluid sample-wrapper text-center" [ngClass]="sampleViewModel.DataContext?.Style?.CustomCssClass +' samplewidget-'+ sampleViewModel.Position?.Columns + 'x' + sampleViewModel.Position?.Rows">
//some other html here
</div>
Run Code Online (Sandbox Code Playgroud)
请注意:使用DynamicComponentLoader动态加载此Component
在我遇到麻烦之后,我发现了几个问题
首先,使用DynamicComponentResolver动态加载此子组件,并传递输入值,如下所示
ngAfterViewInit() {
this.renderWidgetInsideWidgetContainer();
}
renderWidgetInsideWidgetContainer() {
let component = this.storeFactory.getWidgetComponent(this.dataSource.ComponentName);
let …Run Code Online (Sandbox Code Playgroud) 我正在开发一个有角度的项目,我需要找到一种方法,当用户单击按钮时自动滚动到页面底部。
我尝试使用 jQuery 函数 animate() 执行此操作,但这对我不起作用。我也尝试过以下功能:
scrollToBottom() {
let myElement = document.getElementById("myPageId");
myElement.scrollTop = myElement.scrollHeight;
}
Run Code Online (Sandbox Code Playgroud)
该函数仅在我从 html 页面调用它时才有效,而当用户单击按钮时我需要在 ts 文件中使用它。
我正在编写一个聊天应用程序,其中新消息添加到<textarea>. 我希望textarea滚动到底部,因为聊天日志很大。
我该如何实现这个目标?
我尝试了以下操作,scrollTop属性没有滚动我的textarea.
<textarea #chat class="form-control" rows=20 disabled [(ngModel)]="output" [scrollTop]="scroll" name="chatMessages"></textarea>
Run Code Online (Sandbox Code Playgroud)
但是,不会更改到 valuethis.scroll=9999的绑定。我控制台 log ,它的值为,但我的没有到底部!scrollTop9999this.scroll9999textarea
请我需要帮助,谢谢!
我一直在推迟解决我已经有一段时间的错误了。我有以下聊天窗口:
我显示消息的窗口是一个单独的组件(chat-window.component.ts)。我想使用ngOnChanges滚动到底部。
当我们从父组件接收到带有消息的会话(通过异步请求从服务器接收消息)时,我们想要滚动到window元素的底部。我们通过this.scrollToBottom()在ngOnChanges生命周期挂钩中调用类的方法来实现。
确实会调用this.scrollToBottom,但不会滚动到元素的底部。有人知道为什么吗?
chat-window.component.ts:在ngOnchanges中,我们在调用this.scrollToBottom()之前会做一些同步处理
export class ChatboxWindowComponent implements OnChanges, OnInit, AfterViewChecked {
@Input('conversation') conversation;
@ViewChild('window') window;
constructor() { }
ngOnChanges() {
// If the date separators have already been added once, we avoid doing it a second time
const existingDateObj = this.conversation.messages.findIndex((item, i) => item.dateObj);
if (existingDateObj === -1) {
this.conversation.messages.forEach( (item, index, array) => {
if (index !== 0) {
const date1 = new Date(array[index - 1].date);
const date2 = new Date(item.date);
if (date2.getDate() !== date1.getDate() …Run Code Online (Sandbox Code Playgroud) 我有以下聊天:
<div class="container">
<div class="jumbotron" id="chat" >
</div>
<form (submit)="sendUserQueryToServer()">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="search" autocomplete="off" [(ngModel)]="userQuery">
<div class="input-group-btn">
<button class="btn btn-info"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</form>
</div>
Run Code Online (Sandbox Code Playgroud)
使用以下 css:
#chat{
background: lightgray;
max-height: 60vh;
height:60vh;
overflow: auto;
font-size: 1.5em;
}
Run Code Online (Sandbox Code Playgroud)
和脚本:
sendUserQueryToServer() {
$("#chat").append(this.userQuery + "<br \>" );
}
Run Code Online (Sandbox Code Playgroud)
上面的代码被简化了,只留下了相关的部分。
这是相同的代码,“转换”为纯 js:https://jsfiddle.net/wcukrLfk/8/,基本上做同样的事情,你所要做的就是按下小按钮(你需要按下它大约20 次查看行为)。
如您所见,聊天是可滚动的,但是当 max-height 溢出时,它不会自动滚动到页面底部,它只会显示滚动条。如何让聊天自动滚动到页面底部?