我收到了这个消息。在消息上我有一个原型"toggleLike"
。
在保存我的信息之前,喜欢/不喜欢很有效。然后我收到一个错误:
“TypeError:this.isLikedByMe不是函数”
引用行this.isLikedByMe(!this.isLikedByMe());
(见下文)。
但是将"toggleLike"
作为属性(函数)放到对象上会很好。
但为什么原型会导致此错误?
这是我的代码:
Message = function (data) {
var self = this;
self.messageID = data.messageID;
self.messageText = ko.observable(data.messageText);
self.isLikedByMe = ko.observable(data.isLikedByMe || false);
// //this works
// self.toggleLike = function(){
// self.isLikedByMe(!self.isLikedByMe());
// };
return self;
};
Message.prototype.toggleLike = function () {
this.isLikedByMe(!this.isLikedByMe());
};
viewModel = function () {
var self = this;
self.myMessage = ko.observable(
new Message({
messageID: -1,
messageText: 'This is an example'
})
);
self.likeThisMessage = function (data) {
data.toggleLike();
// some more code
};
self.sendMessage = function (data) {
var newmsg = new Message({
ID: -1,
messageText: self.myMessageText(),
});
self.saveMessage(newmsg);
};
self.saveMessage = function (msg) {
if (msg.ID == -1) {
//ajax insert
return $.ajax({
type: "POST",
url: serviceRoot + "InsertMessageItem",
beforeSend: serviceFramework.setModuleHeaders,
data: msg,
cache: false
});
// handle returndata and update msg.ID to value from db.
}
else {
// update ...
}
};
}; // viewModel ends
HTML:
<ul data-bind="with: myMessage">
<li>
<span data-bind="text:messageText"><br/>
<a href="#self" data-bind="visible: !toggleLike(), click:$root.likeThisMessage">Like</a>
<a href="#self" data-bind="visible: toggleLike(),click:$root.likeThisMessage">Unlike</a>
</li>
</ul>
答案 0 :(得分:2)
虽然你的问题不完整,但我会在这里猜测:你在绑定中使用toggleLike
,例如
<button data-bind="click: myMessage.toggleLike">Like</button>
问题不是你正在使用原型上定义的函数,或者原型函数调用构造函数中定义的另一个函数 - 一切正常。
问题是您使用错误的toggleLike
执行this
。在Javascript中,您可以从对象“借用”函数并在完全不同的上下文中执行它们,这意味着它们内部有不同的this
:
var Mary = function Mary() {
this.name = 'Mary';
this.sayName = function sayName() {
console.log('My name is ' + this.name);
};
};
var Sue = function Sue() {
this.name = 'Sue';
};
var mary = new Mary(),
sue = new Sue();
mary.sayName.call(sue);
// executes Marys `sayName` with `this` set to `sue`
在Knockout中,这可能会偶然发生,通常在click
绑定中。在上面的绑定示例中:
<!-- we assume that $data here is your viewmodel -->
<button data-bind="click: myMessage.toggleLike">Like</button>
Click上真正发生的事情是Knockout从myMessage“借用”toggleLike
,并在this
设置为$data
的情况下执行它 - 您的viewmodel:
Message.prototype.toggleLike = function () {
// `this` is now your viewmodel, which does not have `isLikedByMe`
this.isLikedByMe(!this.isLikedByMe());
};
使用bind
来避免这种情况:
<button data-bind="click: myMessage.toggleLike.bind(myMessage)">Like</button>
另一种方法是确保$data
是您尝试调用该函数的对象:
<!-- ko with: myMessage -->
<button data-bind="click: toggleLike">Like</button>
<!-- /ko -->
同样适用。