javascript - Trying to impliment SignalR with Knockout ViewModel - Stack Overflow

admin2025-04-20  0

I have the following code and it appears to not be calling the client and updating the KnockOutJS viewmodel with the information. The GetOuting() gets called on page load and the correct information is fed into the viewmodel. Chrome shows no JS errors in the developer tools. From that point forward I am having trouble figuring out how to troubleshoot it. Any help is appreciated. SignalR Hub

public class Outings : Hub
{
    private static Dictionary<Guid, OutingViewModel> outings = new Dictionary<Guid, OutingViewModel>();

    public void GetOuting(string id)
    {
        var guidID = new Guid(id);
        bool containsOuting = outings.ContainsKey(guidID);
        if (!containsOuting)
        {
            var outingAccessor = new OutingAccessor();
            outingAccessor.ID = guidID;
            outingAccessor.Load();
            var outingVM = new OutingViewModel(outingAccessor);
            outings.Add(guidID, outingVM);
        }
        var outing = outings[guidID];
        this.Clients.updateOuting(outing);
    }

    public void SaveOuting(string outingNumber, OutingViewModel outing)
    {
        var guidID = new Guid(outingNumber);
        outings[guidID] = outing;
        this.Clients.updateOuting(outing);
    }
}

ViewModel

public class OutingViewModel
{
    public OutingViewModel(OutingAccessor outingAccessor)
    {
        ID = outingAccessor.ID;
        OutingNumber = outingAccessor.OutingNumber;
        var outingGeneralAccessor = new OutingGeneralAccessor();
        var outingGeneral = outingGeneralAccessor.GetOutingGeneralByOutingID(outingAccessor.ID);
        this.OutingName = outingGeneral.Name;
    }
    public Guid ID { get; set; }
    public int OutingNumber { get; set; }
    public string OutingName { get; set; }
}

HTML + JavaScript

@model string
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"> </script>
<script src="@this.Url.Content("~/Scripts/jquery.signalR.js")" type="text/javascript">     </script>
<script src="@this.Url.Content("~/Scripts/knockout.js")" type="text/javascript"> </script>
<script type="text/javascript" src="/signalr/hubs"> </script>
<script type="text/javascript">
    $(function() {
        function outingDataViewModel() {
            this.hub = $.connection.outings;
            this.ID = ko.observable();
            this.OutingNumber = ko.observable();
            this.OutingName = ko.observable();
            //Initializes the view model
            this.init = function() {
                this.hub.getOuting('@this.Model');
            };
            this.hub.updateOuting = function(data) {
                ID(data.ID);
                OutingName(data.OutingName);
                OutingNumber(data.OutingNumber);
            };
        }
        var vm = new outingDataViewModel();
        ko.applyBindings(vm);
        // Start the connection
        $.connection.hub.start(function() { vm.init(); });
    });
</script>
<h1>Outing Number</h1>
<div id="OutingSummary">
    <div data-bind="text:OutingNumber"></div>
    <div data-bind="text:OutingName"></div>
</div>

Upon further debugging it appears to be in the lines

ID(data.ID);
OutingName(data.OutingName);
OutingNumber(data.OutingNumber);

It looks like I am getting an exception of "undefined_method" when it tries to set ID. Does that make sense to anyone else?

I have the following code and it appears to not be calling the client and updating the KnockOutJS viewmodel with the information. The GetOuting() gets called on page load and the correct information is fed into the viewmodel. Chrome shows no JS errors in the developer tools. From that point forward I am having trouble figuring out how to troubleshoot it. Any help is appreciated. SignalR Hub

public class Outings : Hub
{
    private static Dictionary<Guid, OutingViewModel> outings = new Dictionary<Guid, OutingViewModel>();

    public void GetOuting(string id)
    {
        var guidID = new Guid(id);
        bool containsOuting = outings.ContainsKey(guidID);
        if (!containsOuting)
        {
            var outingAccessor = new OutingAccessor();
            outingAccessor.ID = guidID;
            outingAccessor.Load();
            var outingVM = new OutingViewModel(outingAccessor);
            outings.Add(guidID, outingVM);
        }
        var outing = outings[guidID];
        this.Clients.updateOuting(outing);
    }

    public void SaveOuting(string outingNumber, OutingViewModel outing)
    {
        var guidID = new Guid(outingNumber);
        outings[guidID] = outing;
        this.Clients.updateOuting(outing);
    }
}

ViewModel

public class OutingViewModel
{
    public OutingViewModel(OutingAccessor outingAccessor)
    {
        ID = outingAccessor.ID;
        OutingNumber = outingAccessor.OutingNumber;
        var outingGeneralAccessor = new OutingGeneralAccessor();
        var outingGeneral = outingGeneralAccessor.GetOutingGeneralByOutingID(outingAccessor.ID);
        this.OutingName = outingGeneral.Name;
    }
    public Guid ID { get; set; }
    public int OutingNumber { get; set; }
    public string OutingName { get; set; }
}

HTML + JavaScript

@model string
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"> </script>
<script src="@this.Url.Content("~/Scripts/jquery.signalR.js")" type="text/javascript">     </script>
<script src="@this.Url.Content("~/Scripts/knockout.js")" type="text/javascript"> </script>
<script type="text/javascript" src="/signalr/hubs"> </script>
<script type="text/javascript">
    $(function() {
        function outingDataViewModel() {
            this.hub = $.connection.outings;
            this.ID = ko.observable();
            this.OutingNumber = ko.observable();
            this.OutingName = ko.observable();
            //Initializes the view model
            this.init = function() {
                this.hub.getOuting('@this.Model');
            };
            this.hub.updateOuting = function(data) {
                ID(data.ID);
                OutingName(data.OutingName);
                OutingNumber(data.OutingNumber);
            };
        }
        var vm = new outingDataViewModel();
        ko.applyBindings(vm);
        // Start the connection
        $.connection.hub.start(function() { vm.init(); });
    });
</script>
<h1>Outing Number</h1>
<div id="OutingSummary">
    <div data-bind="text:OutingNumber"></div>
    <div data-bind="text:OutingName"></div>
</div>

Upon further debugging it appears to be in the lines

ID(data.ID);
OutingName(data.OutingName);
OutingNumber(data.OutingNumber);

It looks like I am getting an exception of "undefined_method" when it tries to set ID. Does that make sense to anyone else?

Share Improve this question edited Feb 28, 2012 at 20:36 PlTaylor asked Feb 28, 2012 at 17:43 PlTaylorPlTaylor 7,56512 gold badges55 silver badges97 bronze badges 4
  • Don't you need to reference jQuery before knockout? – David Fox Commented Feb 28, 2012 at 18:41
  • You only need jQuery if you are using jQery templates with KnockoutJS, otherwise KnockoutJS has no dependencies. – Kevin Junghans Commented Feb 28, 2012 at 18:51
  • Good catch, but this is actually a partial view and the master view contains the jquery reference. I added the jquery reference in the code snippet so as to not raise any false positive answeers...so much for that thought. I'll fix the example shortly. – PlTaylor Commented Feb 28, 2012 at 18:52
  • As a side note you do need to reference jQuery before SignalR. – PlTaylor Commented Feb 28, 2012 at 20:49
Add a ment  | 

1 Answer 1

Reset to default 8

You are correct in where the problem is. When the server calls the updateOuting method and you run the code:

ID(data.ID);
OutingName(data.OutingName);
OutingNumber(data.OutingNumber);

it does not know where to look for ID, OutingName and OutingNumber. You need to specify that these exist on the view model object. One solution which solves your problem would be to change the javascript code to the following:

<script type="text/javascript">
    $(function () {
        function outingDataViewModel() {
            var self = this;
            self.hub = $.connection.outings;
            self.ID = ko.observable();
            self.OutingNumber = ko.observable();
            self.OutingName = ko.observable();
            //Initializes the view model
            self.init = function () {
                self.hub.getOuting('@Guid.NewGuid().ToString()');
            };
            self.hub.updateOuting = function (data) {
                self.ID(data.ID);
                self.OutingName(data.OutingName);
                self.OutingNumber(data.OutingNumber);
            };
        }
        var vm = new outingDataViewModel();
        ko.applyBindings(vm);
        // Start the connection
        $.connection.hub.start(function () { vm.init(); });
    });
</script>

Hope it helps!

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745111996a285638.html

最新回复(0)