You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Knockout.js中deleteComment函数报错TypeError: this.comments未定义

解决Knockout.js中deleteComment函数里this.comments未定义的问题

这个问题的核心是函数执行时this的指向错误,我来帮你拆解并解决:

问题根源

你在删除按钮的点击绑定里写了:

<button data-bind="visible: display(), click: $parent.deleteComment.bind($data, $index)" >Delete Comment</button>

这里的bind($data)把deleteComment函数的this绑定成了当前循环的Comment对象(也就是单条评论的实例),而不是你的AppViewModel。Comment对象里并没有comments这个属性,所以自然会抛出this.comments is undefined的错误。

反观enterComment能正常工作,是因为它的绑定在form上,此时的$data就是AppViewModel实例,bind($data)让函数里的this正确指向了ViewModel,所以能访问到this.comments。

三种可行解决方案

方案1:修正bind的上下文

把按钮绑定里的bind($data)改成bind($parent),让deleteComment的this指向AppViewModel:

<button data-bind="visible: display(), click: $parent.deleteComment.bind($parent, $index)" >Delete Comment</button>

这样在deleteComment函数里,this就会正确指向ViewModel,this.comments就能正常调用了。

方案2:在ViewModel里保存self引用

这是Knockout开发里的经典技巧,在AppViewModel构造函数开头添加var self = this;,之后所有需要访问ViewModel属性的地方都用self代替this,不管函数的this怎么变化,都能拿到正确的ViewModel引用:

var AppViewModel = function (commentList, userList) {
    var self = this; // 保存ViewModel的引用
    this.displayButton = ko.observable(false);
    this.comments = ko.observableArray();
    // ... 其他初始化代码 ...

    this.deleteComment = function(index){
        self.comments.splice(index,1); // 用self代替this
    }

    // ... 其他函数 ...
};

方案3:使用ES6箭头函数

箭头函数会自动继承外层作用域的this,直接用箭头函数定义deleteComment,就能让函数里的this始终指向AppViewModel:

this.deleteComment = (index) => {
    this.comments.splice(index,1);
}

这种写法更简洁,也不需要操心绑定的上下文问题。

额外小提醒

你的代码里username变量没有用var/let声明,会变成全局变量,建议改成局部变量或者挂载到ViewModel上,比如:

var username;
$.ajax({
    url: "http://localhost/sem4/recept/UserInfo.php",
    async: false,
    dataType: 'json',
    success: function(data) {
        username = data.username;
    }
});

这样代码会更规范,也避免全局变量污染。

内容的提问来源于stack exchange,提问作者youssef taoudi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:50:59