Knockout.js中this与that的区别及this.view/that.view含义咨询
关于Knockout.js中this/that及view相关问题的解答
嗨,作为Knockout.js新手碰到这些this和that的困惑太正常啦,我来给你拆解清楚~
1) Knockout.js中this和that的区别是什么?
其实这本质上是JavaScript里上下文绑定的问题,Knockout里只是场景更典型而已:
this的指向是动态的,会根据函数被调用的方式变化。在Knockout的ViewModel方法里,默认情况下this指向当前的ViewModel实例;但如果是在异步回调(比如setTimeout)、第三方库的回调(比如Highcharts的配置函数)里,this会变成其他对象(比如浏览器的window,或者Highcharts的图表实例)。- 而
that(很多人也用self)是我们手动创建的变量,用来保存外层上下文的this——通常就是ViewModel实例。这样在内部回调函数里,即使this变了,我们还能通过that访问到ViewModel的属性和方法。
举个简单的例子:
var MyVM = function() { var that = this; // 保存当前ViewModel实例到that this.chartTitle = "我的图表"; this.initChart = function() { // 这里的this还是ViewModel实例 Highcharts.chart({ title: { text: this.chartTitle }, // 假设一个回调函数 load: function() { // 这里的this是Highcharts的图表实例,不是ViewModel了 console.log(that.chartTitle); // 用that就能拿到ViewModel的标题 } }); }; };
2) this.view和that.view分别代表什么含义?
在你的代码场景里:
this.view指的是当前函数执行上下文里的view对象,这个对象通常关联着当前有效的DOM元素(比如你的图表容器div)或者Knockout视图相关的实例。that.view则是你之前用var that = this保存的外层上下文的view对象——比如你在ViewModel初始化时把当时的this(ViewModel实例)存成that,那that.view就是当时ViewModel对应的view对象。
结合你的Highcharts问题分析
你说设置renderTo: that.view首次加载正常,但重新加载时图表不显示,换成this.view就没问题。这大概率是因为:
第一次加载时,that.view指向的是当时有效的图表容器DOM节点;但重新加载时,原来的DOM节点可能已经被Knockout重新渲染销毁了,或者你的ViewModel已经重新实例化,that还是指向旧的ViewModel实例,对应的that.view已经是无效的DOM节点了。而this.view在重新加载的函数调用里,是当前上下文(新的ViewModel实例或者当前有效的视图上下文)里的有效DOM节点,所以Highcharts能正确找到容器渲染图表。
比如你可能的代码场景:
var ChartVM = function() { var that = this; this.view = document.getElementById('chart-div'); this.reloadChart = function() { // 重新加载时,that.view可能是旧的已被移除的div // 而this.view是当前存在的新div(比如Knockout重新渲染后生成的) new Highcharts.Chart({ renderTo: this.view, chart: { height: this.view.parentNode.offsetHeight }, // ...其他配置 }); }; };
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

