Knockout js点击模型内的事件

时间:2016-11-28 05:48:41

标签: javascript jquery knockout.js

以下是包含帖子和评论功能的代码。我在data-bind="click: addComment"data-bind="click: addPost"等ul标记点击事件中绑定视图。它工作正常。

我的问题是,将data-bind="click: addComment"置于另一个视图中时,它将无效。我需要将data-bind="click: addComment"保留在另一个视图中,并且必须点击帖子模型中的self.addComment - 有人可以帮忙吗?

<div class="publishContainer">
<textarea class="msgTextArea" id="txtMessage" data-bind="value: newMessage,  jqAutoresize: {}" style="height:3em;" placeholder="What's on your mind?">   </textarea>
<input type="button" data-url="/Wall/SavePost" value="Share" id="btnShare" data-bind="click: addPost">
</div>
<ul id="msgHolder" data-bind="foreach: posts">
 <li class="postHolder">
    <img data-bind="attr: { src: PostedByAvatar }"><p><a data-bind="text: PostedByName"></a>: <span data-bind="    html: Message"></span></p>
    <div class="postFooter">
        <span class="timeago" data-bind="text: PostedDate"></span>&nbsp;<a class="linkComment" href="#" data-bind="    click: toggleComment">Comment</a>
        <div class="commentSection">
            <ul data-bind="foreach: PostComments">
                <li class="commentHolder">
                    <img  data-bind="attr: { src: CommentedByAvatar }"><p><a data-bind="text: CommentedByName"></a>: <span data-bind="    html: Message"></span></p>
                    <div class="commentFooter"> <span class="timeago" data-bind="text: CommentedDate"></span>&nbsp;</div>
                </li>
            </ul>
            <div style="display: block" class="publishComment">
                <textarea class="commentTextArea" data-bind="value: newCommentMessage, jqAutoresize: {}" placeholder="write a comment..."></textarea>
                <input type="button"  value="Comment" class="btnComment" data-bind="click: addComment"/>
            </div>
        </div>
    </div>
</li>
</ul>
</div>

//second view//
<div class="publishContainer">
    <input type="button"  value="Comment" class="btnComment" data-bind="click: addComment"/>
 <div>

和JS:

//Post Model
function Post(data) {
  var self = this;
  data = data || {};
  self.PostId = data.PostId;
  self.Message = ko.observable(data.Message || "");
  self.PostedBy = data.PostedBy || "";
  self.PostedByName = data.PostedByName || "";
  self.PostedByAvatar = data.PostedByAvatar || "";
  self.PostedDate = getTimeAgo(data.PostedDate);
  self.error = ko.observable();
  self.PostComments = ko.observableArray();

  self.newCommentMessage = ko.observable();
  self.addComment = function () {
    var comment = new Comment();
    comment.PostId = self.PostId;
    comment.Message(self.newCommentMessage());
    return $.ajax({
        url: commentApiUrl,
        dataType: "json",
        contentType: "application/json",
        cache: false,
        type: 'POST',
        data: ko.toJSON(comment)
    })
   .done(function (result) {
       self.PostComments.push(new Comment(result));
       self.newCommentMessage('');
   })
   .fail(function () {
       error('unable to add post');
   }); 
  }
  if (data.PostComments) {
    var mappedPosts = $.map(data.PostComments, function (item) { return new    Comment(item); });
    self.PostComments(mappedPosts);
  }
  self.toggleComment = function (item,event) {       
    $(event.target).next().find('.publishComment').toggle();
  }
}

// Comment Model:

function Comment(data) {
  var self = this;
  data = data || {};   
  self.CommentId = data.CommentId;
  self.PostId = data.PostId;
  self.Message = ko.observable(data.Message || "");
  self.CommentedBy = data.CommentedBy || "";
  self.CommentedByAvatar = data.CommentedByAvatar || "";
  self.CommentedByName = data.CommentedByName || "";
  self.CommentedDate = getTimeAgo(data.CommentedDate);
  self.error = ko.observable();    
}

function viewModel() {
  var self = this;
  self.posts = ko.observableArray();
  self.newMessage = ko.observable();
  self.error = ko.observable();
  self.loadPosts = function () {
    //To load existing posts
    $.ajax({
        url: postApiUrl,
        dataType: "json",
        contentType: "application/json",
        cache: false,
        type: 'GET'
    })
        .done(function (data) {
            var mappedPosts = $.map(data, function (item) { return new Post(item); });
            self.posts(mappedPosts);
        })
        .fail(function () {
            error('unable to load posts');
        });
  }

  self.addPost = function () {
    var post = new Post();
    post.Message(self.newMessage());
    return $.ajax({
        url: postApiUrl,
        dataType: "json",
        contentType: "application/json",
        cache: false,
        type: 'POST',
        data:  ko.toJSON(post)
    })
   .done(function (result) {           
       self.posts.splice(0,0,new Post(result));
       self.newMessage('');
     })
   .fail(function () {
            error('unable to add post');
    });
 }
 self.loadPosts();
 return self;
}; 

ko.applyBindings(new  viewModel(),documentgetElementByClassName(publishContainer));

1 个答案:

答案 0 :(得分:0)

您的问题的一个选项是应该有observable 它包含selectedPost / currentPost。在按下添加评论

之前,应该更新此道具

然后像下面的那样更新你的viewModel。

function viewModel() {
    var self = this;
    self.posts = ko.observableArray();
    self.newMessage = ko.observable();
    self.error = ko.observable();
    self.loadPosts = function() {
        //To load existing posts
        $.ajax({
                url: postApiUrl,
                dataType: "json",
                contentType: "application/json",
                cache: false,
                type: 'GET'
            })
            .done(function(data) {
                var mappedPosts = $.map(data, function(item) {
                    return new Post(item);
                });
                self.posts(mappedPosts);
            })
            .fail(function() {
                error('unable to load posts');
            });
    }

    self.addPost = function() {
        var post = new Post();
        post.Message(self.newMessage());
        return $.ajax({
                url: postApiUrl,
                dataType: "json",
                contentType: "application/json",
                cache: false,
                type: 'POST',
                data: ko.toJSON(post)
            })
            .done(function(result) {
                self.posts.splice(0, 0, new Post(result));
                self.newMessage('');
            })
            .fail(function() {
                error('unable to add post');
            });
    }

    self.selectedPost = ko.observable(); // You have to update this property, before you click on Add Comment from second view.

    self.addComment = function() {
        var comment = new Comment();
        comment.PostId = self.selectedPost.PostId;
        comment.Message(self.newCommentMessage());
        return $.ajax({
                url: commentApiUrl,
                dataType: "json",
                contentType: "application/json",
                cache: false,
                type: 'POST',
                data: ko.toJSON(comment)
            })
            .done(function(result) {
                self.selectedPost.PostComments.push(new Comment(result));
                self.newCommentMessage('');
            })
            .fail(function() {
                error('unable to add post');
            });
    }

    self.loadPosts();
    return self;
};

并且,在您所谓的第一个视图中,更新添加注释部分,如下所示

<div style="display: block" class="publishComment">
                <textarea class="commentTextArea" data-bind="value: newCommentMessage, jqAutoresize: {}" placeholder="write a comment..."></textarea>
                <input type="button"  value="Comment" class="btnComment" data-bind="click: $parent.addComment"/>
            </div>