te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - knockout throws Message: TypeError: <xxx> is not a function. What does it mean? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - knockout throws Message: TypeError: <xxx> is not a function. What does it mean? - Stack Overflow

programmeradmin4浏览0评论

I have this code:

<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="ment_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));

But I get this error when the showMoreChats function is called:

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

What does it mean?

I have this code:

<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="ment_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));

But I get this error when the showMoreChats function is called:

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

What does it mean?

Share Improve this question edited Jul 3, 2012 at 2:06 ladookie asked Jul 3, 2012 at 1:21 ladookieladookie 1,3714 gold badges21 silver badges25 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

It's not that CommentList is undefined, it's just that it's not an observable (hence not a function). The reason being that in your ajax callback, you are just pushing the 'chat' objects received from your server "as is". You're not creating for example a new observableArray called CommentList, but you're just putting a bare array CommentList - hence the thrown error by KO.

You would need to make the same transformation as you did when constructing self.chats in the viewmodel constructor, e.g.:

$.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("")
        }
    );
});

By the way, you should also take a look at the ko.mapping plugin, it can do this transformation for you.

Edit: Also, for better performance you shouldn't push each individual item into the observable array, but add them in one bulk operation, something like:

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

Found this question via Google, adding my case for reference. It's really, really stupid; yet this is a mistake caused by inattention I often make:

When using one of the ko.utils array functions (arrayMap, arrayForEach, arrayFirst, etc.), Knockout will throw this error when you forget to specify the source array, eg. when you do:

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

instead of:

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

It means your binding cannot detect CommentList, i.e. CommentList is undefined in the current context.

发布评论

评论列表(0)

  1. 暂无评论