SignalR&淘汰父母 - 孩子回调问题

时间:2013-04-08 22:14:03

标签: knockout.js signalr signalr-hub

我有以下javascript视图模型(需要重构,但我希望首先让所有功能正常运行),并且设置是一个MessagesViewModel,它包含 MessageViewModels 的集合。 MessageViewModel 包含 FeedbackViewModels 的集合。发布新消息时,一切正常,集线器回调并更新UI。问题是当我向评论添加反馈时,反馈会持续存在于数据库中,但不会调用回调 - 请参阅代码:

public bool AddMessageFeedback(string txtFeedbackComments, string hdnMessageId, int userId)
    {
        bool result = false;
        try
        {
            var message = new Message
                {
                    SDUID = userId,
                    MessageText = txtFeedbackComments,
                    MessageDate = DateTime.Now.Date,
                    MessageTime = Convert.ToDateTime(DateTime.Now.TimeOfDay.ToString()),
                    Poster = UserManager.GetItem(userId),
                    MessageDateAsString = DateTime.Now.Date.ToString(),
                    MessageTimeAsString = DateTime.Now.TimeOfDay.ToString(),
                    MessageDay = DateTime.Now.DayOfWeek.ToString()
                };

            MessageManager.AddMessageFeedback(message, Convert.ToInt64(hdnMessageId));

            Clients.All.messageFeedbackAdded(message);
            result = true;
        }
        catch (Exception)
        {
            Clients.Caller.raiseError("Unable to add feedback.");
        }

        return result;
    }

的ViewModels

$(function () {

    $(function () {

        function messageFeedbackViewModel(feedbackText, poster, messageDay, messageDate, messageTime, owner) {
            this.poster = poster;
            this.feedbackText = feedbackText;
            this.datePosted = messageDay.substr(0, 3) + ', ' + messageDate.substr(0, 10) + ' ' + messageTime.substr(0, 5);

            var self = this;
        }

        function messageViewModel(MessageID, messageText, SDUID, SportID, poster, sport, feedback, messageDate, messageDay, messageTime, owner) {
            this.hub = $.connection.messagesHub;

            //message variables, initialised from params
            this.MessageID = MessageID;
            this.SDUID = SDUID;
            this.SportID = SportID;
            this.poster = poster;
            this.messageText = messageText;
            this.sport = sport;

            this.datePosted = messageDay.substr(0, 3) + ', ' + messageDate.substr(0, 10) + ' ' + messageTime.substr(0, 5);

            //message feedback collection
            this.messageFeedback = ko.observableArray([]);

            //html variables
            this.newMessageFeedback = ko.observable();

            //reference to message feedback collection
            var messageFeedback = this.messageFeedback;

            var self = this;
            var notify = true;

            //callback from server side hub
            this.hub.client.messageFeedbackAdded = function (newMessageFeedback) {
                self.messageFeedback.push(new messageFeedbackViewModel(newMessageFeedback.MessageFeedbackText, newMessageFeedback.Poster, newMessageFeedback.MessageFeedbackDay, newMessageFeedback.MessageFeedbackDateAsString, newMessageFeedback.MessageFeedbackTimeAsString, self));
            };

            //build message feedback VM's
            if (feedback){
                if (feedback.length > 0) {
                    var mappedFeedbackMessages = $.map(feedback, function (feed) {
                        return new messageFeedbackViewModel(feed.MessageFeedbackText, feed.Poster, feed.MessageFeedbackDay, feed.MessageFeedbackDateAsString, feed.MessageFeedbackTimeAsString, self);
                    });
                    messageFeedback(mappedFeedbackMessages);
                }
            }

            //client side post
            this.createMessageFeedback = function () {
                var innerMessageFeedback = this.newMessageFeedback();
                var userId = $('#userID').val();
                var messageId = this.MessageID;
                this.hub.server.addMessageFeedback(innerMessageFeedback, messageId, userId).done(function () {
                    console.log('message saved!');
                }).fail(function (error) {
                    console.warn(error);
                });
                this.newMessageFeedback('');
            };
        }

        function messagesViewModel() {
            this.hub = $.connection.messagesHub;

            //messages collection
            this.messages = ko.observableArray([]);

            //html variables
            this.newMessageMessageID = ko.observable();
            this.newMessageSDUID = ko.observable();
            this.newMessageSportID = ko.observable();
            this.newMessagePoster = ko.observable();
            this.newMessageMessageText = ko.observable();

            //reference to messages collection
            var messages = this.messages;

            var self = this;
            var notify = true;
            var userId = $('#userID').val();

            //load messages, calling server side hub method
            this.init = function () {
                this.hub.server.getAll(userId);
            };

            //callback from server side hub sending messages to client
            this.hub.client.allMessagesRetrieved = function (allMessages) {
                var mappedMessages = $.map(allMessages, function (message) {
                    return new messageViewModel(message.MessageID, message.MessageText, message.SDUID, message.SportID, message.Poster, message.Sport, message.Feedback, message.MessageDateAsString, message.MessageDay, message.MessageTimeAsString, self);
                });

                messages(mappedMessages);
            };

            //callback from server side hub sending error messages to client
            this.hub.client.raiseError = function (error) {
                $("#error").text(error);
            };

            //call back from server side hub sending new message and pushing to collection
            this.hub.client.messageCreated = function (newMessage) {
                messages.splice(0, 0, new messageViewModel(newMessage.MessageID, newMessage.MessageText, newMessage.SDUID, newMessage.SportID, newMessage.Poster, newMessage.Sport, newMessage.Feedback, newMessage.MessageDateAsString, newMessage.MessageDay, newMessage.MessageTimeAsString, self));
            };

            //client side method from form post
            this.createMessage = function () {
                var selectedSport = $('#ddlSport option:selected').text();

                var message = { messageText: this.newMessageMessageText(), SDUID: userId, SportID: this.newMessageSportID(), Sport: selectedSport };

                this.hub.server.add(message).done(function () {
                    console.log('message saved!');
                }).fail(function (error) {
                    console.warn(error);
                });

                this.newMessageMessageText('');
                this.newMessageSDUID('');
                this.newMessageSportID('');
                this.newMessagePoster('');
            };
        }

        //set up the viewmodel
        var viewModel = new messagesViewModel();
        ko.applyBindings(viewModel);

        //call to initialise
        $.connection.hub.start(function () {
            viewModel.init();
        });
    });
});

任何帮助都将不胜感激,谢谢。

1 个答案:

答案 0 :(得分:1)

问题是您在启动集线器连接后添加了hub.client.messageFeedbackAdded回调。

当您创建hub.client.messageFeedbackAddedmessageViewModel触发时发生的新allMessagesRetrieved时,会添加messageCreated回调。在集线器连接开始后,这两个事件都会发生。

如果确实想要在开始连接后添加客户端中心方法,则可以使用hubProxy.on( eventName, handler(args...))

$.connection.messagesHub.on("messageFeedbackAdded", function (newMessageFeedback) { /*...*/ });

然而,这不是你应该做的。在调用hub.client.messageFeedbackAdded以及$.connection.hub.startallMessagesRetreivedraiseError之前,您应该只定义一次messageCreated

您需要将父消息ID(可能是服务器上的hdnMessageId)传递给messageFeedbackAdded,以便客户端知道要添加反馈的消息,但无论如何都需要消息ID。

如果您使用hubProxy.on内的messageViewModel为每条消息添加messageFeedbackAdded的新处理程序,则无论是Clients.All.messageFeedbackAdded(message);的每次后续调用,都会调用您的处理程序反馈实际留给哪条消息。这意味着您的客户会在每条消息中显示每条新添加的反馈,这显然不是您想要的。