【发布时间】:2016-07-13 05:03:24
【问题描述】:
我一直在研究一个简单的聊天显示自动滚动指令:
@Directive({
selector: "[autoScroll]"
})
export class AutoScroll {
@Input() inScrollHeight;
@Input() inClientHeight;
@HostBinding("scrollTop") outScrollTop;
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
if (changes["inScrollHeight"] || changes["inClientHeight"]) {
this.scroll();
}
};
scroll() {
this.outScrollTop = this.inScrollHeight - this.inClientHeight;
};
}
当我设置enableProdMode() 并且ChangeDetectionStrategy 设置为默认值时,该指令将起作用,但在“开发模式”下我得到一个异常。我可以将ChangeDetectionStrategy 设置为onPush,在这种情况下不会发生异常但滚动会滞后。
有没有办法更好地构造这段代码,以便更新 Dom 然后调用 Scroll 函数?我尝试过setTimeout(),但这会使延迟更糟,尝试使用ChangeDetectorRef 并订阅可观察对象以触发markForCheck()。使用ngAfterViewChecked() 会导致浏览器崩溃。
@Component({
selector: "chat-display",
template: `
<div class="chat-box" #this [inScrollHeight]="this.scrollHeight" [inClientHeight]="this.clientHeight" autoScroll>
<p *ngFor="#msg of messages | async | messageFilter:username:inSelectedTarget:inTargetFilter:inDirectionFilter" [ngClass]="msg.type">{{msg.message}}</p>
</div>
`,
styles: [`.whisper {
color: rosybrown;
}`],
directives: [NgClass, AutoScroll],
pipes: [AsyncPipe, MessageFilterPipe],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChatDisplay implements OnInit {
username: string;
@Input() inSelectedTarget: string;
@Input() inTargetFilter: boolean;
@Input() inDirectionFilter: boolean;
messages: Observable<ChatType[]>;
constructor(private socketService_: SocketService, private authService_: AuthService) {
this.username = this.authService_.username;
};
ngOnInit() {
}
}
这是在开发模式下触发的异常:
例外:表达式 'this.scrollHeight in ChatDisplay@1:40' 在检查后已更改。以前的值:“417”。当前值: [this.scrollHeight in ChatDisplay@1:40] 中的“420” angular2.dev.js (23083,9)
【问题讨论】:
-
“异常”到底是什么会很有趣。
-
这是在开发模式下发生两次更改检测时,检查之间的表达式“this.scrollHeight”不同。就像 observable 将消息推送到显示器一样,这会增加 scrollHeight,所以检查之间是不同的,我认为这就是正在发生的事情。
-
您能否在您的问题中添加确切的错误消息?
-
您在哪里订阅
scroll事件?什么叫scroll()? -
添加了异常消息。当指令检测到 ngOnChanges 生命周期钩子中输入属性的任何更改时,就会发生滚动。
标签: angular angular2-directives angular2-changedetection