将SignalR中的JSON传递回Knockout ViewModel

时间:2014-04-03 18:38:31

标签: c# json knockout.js signalr

我认为我没有正确地做到这一点,而且我还没有真正弄明白为什么。我是Knockout和SignalR的新手,只是穿透它。

目前,如果我在我的页面上放置一个调试HTML元素并将其数据绑定到ViewModel上的dashboard,我将获得所有JSON输出。

虽然,如果我尝试进行任何数据绑定,我会得到未定义的错误。例如,我尝试执行以下操作:

<div data-bind="with: dashboard">
    <table class="table table-striped">
        <tr>
            <th>Staff</th>
            <th>Certification</th>
            <th>Code</th>
            <th>Type</th>
            <th>Organization</th>
            <th>Location</th>
            <th>Requirement</th>
            <th>Requirement Type</th>
            <th>Start</th>
            <th>Term</th>
            <th>End</th>
        </tr>
        <tr data-bind="foreach: expiringRequirements">
            <td data-bind="text: Name"></td>
            <td data-bind="text: Certification"></td>
        </tr>
    </table>
</div>

我为undefined收到expiringRequirements错误,但我也得到了ExpiringRequirements的未定义(实际上是我的JSON中的吐出)。

任何人都可以帮助并告诉我我做错了什么吗?据我所知,SignalR部分工作正常。

此外,将各个可观察对象移动到ViewModel中会更有意义吗?理想情况下,如果只有一个部分发生变化,我会直接将其定位,我觉得不必将它们放入模型中。

模型和ViewModels

var dashboardViewModel = function (data) {
    var self = this;

    self.hub = $.connection.dashboardHub;
    self.expiringRequirements = ko.observableArray([]);
    self.completedNotes = ko.observable();
    self.newUsers = ko.observableArray([]);
    self.reportables = ko.observableArray([]);

    self.init = function (portalId) {
        self.hub.server.fetchDataReportingItemsAsync(portalId);
    }

    self.updateEntireDashboard = function (result) {
        self.expiringRequirements(data.ExpiringRequirements);
        self.completedNotes(data.CompletedNotes);
        self.newUsers(data.NewUsers);
        self.reportables(data.Reportables);
    }
};

$(function () {
    var viewModel = new dashboardViewModel();
    var portalId = <%= PortalId %>

    ko.applyBindings(viewModel);

    $.connection.hub.logging = true;

    hub = $.connection.dashboardHub;
    $.connection.hub.start().done(function () {
        viewModel.init(portalId);
    });

    hub.client.upadateDashboardData = function (data) {
        viewModel.updateEntireDashboard(JSON.parse(data));
    }


});

编辑:更新了我的viewmodel并删除了模型,因为viewmodel的各个部分无论如何都是独立的,可以独立更新。更有意义的是将它压平给我。但是,绑定它仍然没有功能

集线器

public async void FetchDataReportingItemsAsync(int portalId)
{
    PortalId = portalId;
    var getNewUsersTask = GetNewUsersAsync();
    var getReportablesTask = GetReportablesAsync();
    var getExpiringReqsTask = GetExpiringRequirementsAsync();
    //var getCompletedNotesTask = GetCompletedNotesAsync();

    //Ensure that this includes every awaitable task
    await Task.WhenAll(getNewUsersTask, getReportablesTask, getExpiringReqsTask);

    DashboardReportingViewModel vm = new DashboardReportingViewModel()
    {
        NewUsers = getNewUsersTask.Result,
        Reportables = getReportablesTask.Result,
        ExpiringRequirements = getExpiringReqsTask.Result
        //CompletedNotes = getCompletedNotesTask.Result
    };

    Clients.All.updateDashboardData(vm);
}

3 个答案:

答案 0 :(得分:1)

如果你做viewModel.dashboard(data);它不会起作用,因为它只会用数据中的不可观察属性替换observable,如果你使用viewModel.dashboard(new Dashboard(data));它也不会工作,因为它实际上是创建与dom绑定的不同的新observable。我知道用新数据更新一堆现有observable的最好方法是使用knockout mapping插件。

答案 1 :(得分:0)

我没有意识到我将Viewmodel的updateEntireDashboard中的参数更改为结果,并且未将data.ExpiringRequirements等更新为result.ExpiringRequirements

现在按预期工作。

答案 2 :(得分:0)

我认为你的with binding错了:

<div data-bind="with: dashboard">

这使得viewModel.dashboard成为所有其他数据绑定的binding-context

由于viewModel.dashboard未定义,因此您可以获得未定义的错误&#34;。