knockout.js - SignalR & Knockout parent - child callback issue -
i have following javascript view models (need refactoring, i'm looking functioning first), , setup messagesviewmodel holds collection of messageviewmodels , messageviewmodel holds collection of feedbackviewmodels. when posting new message, works fine , hub calls , ui updated. issue when add feedback comment, feedback persists database, callback isn't invoked - see code:
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 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 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 message feedback collection var messagefeedback = this.messagefeedback; var self = this; var notify = true; //callback 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 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 server side hub sending messages 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 server side hub sending error messages client this.hub.client.raiseerror = function (error) { $("#error").text(error); }; //call server side hub sending new message , pushing 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 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 viewmodel var viewmodel = new messagesviewmodel(); ko.applybindings(viewmodel); //call initialise $.connection.hub.start(function () { viewmodel.init(); }); }); });
any appreciated, thanks.
the problem adding hub.client.messagefeedbackadded
callback after have started hub connection.
the hub.client.messagefeedbackadded
callback being added when create new messageviewmodel
happens when allmessagesretrieved
or messagecreated
fires. both of these events happen after hub connection starts.
if really want add client hub method after start connection use hubproxy.on( eventname, handler(args...))
.
$.connection.messageshub.on("messagefeedbackadded", function (newmessagefeedback) { /*...*/ });
however isn't should do. should define hub.client.messagefeedbackadded
once before calling $.connection.hub.start
along allmessagesretreived
, raiseerror
, messagecreated
.
you need pass parent message id (which presumably hdnmessageid
on server) messagefeedbackadded
client knows message add feedback to, message id necessary regardless.
if use hubproxy.on
inside of messageviewmodel
add new handler messagefeedbackadded
every message, handler invoked each subsequent invocation of clients.all.messagefeedbackadded(message);
no matter message feedback left for. means client show each piece of newly added feedback every message not want.
Comments
Post a Comment