knockout throws消息:TypeError:<xxx>不是函数。这是什么意思?</xxx>

时间:2012-07-03 01:21:08

标签: javascript knockout.js

我有这段代码:

<ul id="chats" data-bind="foreach: chats">
   <li>
      <div class="chat_response" data-bind="visible: CommentList().length == 0">
        <form data-bind="submit: $root.addComment">
           <input class="comment_field" placeholder="Comment…" data-bind="value: NewCommentText" />
        </form>
      </div>
      <a class="read_more_messages" data-bind="visible: moreChats, click: showMoreChats">Read More Messages...</a>
   </li>
</ul>

function ChatListViewModel(chats) {
   // Data
   var self = this;

   self.chats = ko.observableArray(ko.utils.arrayMap(chats, function (chat) {
       return { CourseItemDescription: chat.CourseItemDescription,
           CommentList: ko.observableArray(chat.CommentList),
           CourseItemID: chat.CourseItemID,
           UserName: chat.UserName,
           ChatGroupNumber: chat.ChatGroupNumber,
           ChatCount: chat.ChatCount,
           NewCommentText: ko.observable("")
       };
   }));

   self.moreChats = ko.observable(true);

   self.showMoreChats = function () {
       var LastChatGroupNumber = self.chats()[self.chats().length - 1].ChatGroupNumber;

       $.ajax({
           url: $.CourseLogic.dataitem.GetMoreChatsUrl,
           data: "{chatGroupNumber: " + ko.toJSON(LastChatGroupNumber + 1) + "}",
           type: "post",
           contentType: "application/json",
           success: function (chats) {
               var chatList = self.chats();
               $.each(chats, function (index, chat) {
                   self.chats.push(chat);
               });
           }
       });
   }

}

ko.applyBindings(new ChatListViewModel(initialData));

但是在调用showMoreChats函数时出现此错误:

Unable to parse bindings. Message: TypeError: CommentList is not a function; Bindings value: visible: CommentList().length == 0

这是什么意思?

3 个答案:

答案 0 :(得分:7)

并不是CommentList未定义,只是它不是一个可观察的(因此不是一个函数)。原因是在你的ajax回调中,你只是按“原样”推送从服务器收到的“聊天”对象。你不是要创建一个名为CommentList的新的observableArray,但是你只是放置一个裸数组CommentList - 因此KO抛出了错误。

您需要进行与在viewmodel构造函数中构造self.chats时所做的相同的转换,例如:

$.each(chats, function(index, chat) {
    self.chats.push(
        {
            CourseItemDescription: chat.CourseItemDescription,
            CommentList: ko.observableArray(chat.CommentList),
            CourseItemID: chat.CourseItemID,
            UserName: chat.UserName,
            ChatGroupNumber: chat.ChatGroupNumber,
            ChatCount: chat.ChatCount,
            NewCommentText: ko.observable("")
        }
    );
});

顺便说一下,你还应该看看ko.mapping插件,它可以为你做这个转换。

编辑:另外,为了获得更好的性能,您不应将每个项目推送到可观察数组中,而是将它们添加到一个批量操作中,例如:

self.chats( self.chats().concat( ko.utils.arrayMap(chats, function(chat) {
    return { /* ... same as before ... */ };
} ) );

答案 1 :(得分:3)

通过Google发现此问题,添加我的案例以供参考。 这真的非常愚蠢;但这是我经常做的疏忽造成的错误:

当使用其中一个ko.utils数组函数(arrayMap,arrayForEach,arrayFirst等)时,如果忘记指定源数组,Knockout将抛出此错误,例如。当你这样做时:

ko.utils.arrayMap(function(item) { ... })

而不是:

ko.utils.arrayMap(myArray, function(item) { ... });

答案 2 :(得分:0)

这意味着您的绑定无法检测到CommentList,即在当前上下文中未定义CommentList。