Asp.net web api 淘汰:可观察的,内部可观察的仅在UI中更新,但在传递到服务器时保持不变?

Asp.net web api 淘汰:可观察的,内部可观察的仅在UI中更新,但在传递到服务器时保持不变?,asp.net-web-api,knockout.js,signalr,Asp.net Web Api,Knockout.js,Signalr,我有一个可观察的物体,里面有两个可观察的属性: self.matchModel = ko.observable(); 模型如下所示: function toKnockOutObservable(data) { return { Id: data.Id, TeamId: data.TeamId, TeamName: data.TeamName, OpponentName: data.OpponentName,

我有一个可观察的物体,里面有两个可观察的属性:

self.matchModel = ko.observable();
模型如下所示:

function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
 self.AddScoreToOpponentTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        taskHub.server.updateLiveScore(self.matchModel());
    }
var url = 'api/MainPage/GetMatchById?matchId=' + matchId;

$.post(url,
    function (data) {
        model.livematch(data);
        console.log(data);
        model.matchModel(toKnockOutObservable(data));
    }, 'json');

ko.applyBindings(model, document.getElementById("livematch"));
function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        var teamScore = self.matchModel().TeamScore();  // Teamscore is 0 (OK)
        teamScore += 1;
        self.matchModel().TeamScore(teamScore);
        taskHub.server.updateLiveScore(self.matchModel()); // When passed to back-end TeamScore property is still 0 (WRONG).
        console.log("Ny teamscore verdi i modellen " + self.matchModel().TeamScore()); // Teamscore is now 1 (OK)
    }
<!--ko with: matchModel-->
    <%--// HOME TEAM--%>
    <div class="col-sm-12">
        <div class="widget-container row">
            <div class="col-sm-12 widget-box">
                <div class="widget-content scrollable visible">
                    <div class="header">
                        <p>
                            <!--ko text: TeamName-->
                            <!--/ko-->
                        </p>
                        <p>
                            <img src="Content/Images/liveupdate.gif" />
                        </p>
                    </div>
                    <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10">
                        <h1><!--ko text: TeamScore--><!--/ko--></h1>
                    </div>
                    <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2">
                <button data-bind="click: $parent.AddScoreToHomeTeam" type="button" class="btn btn-primary btn-lg" id="team_plus" style="width: 100%; height:100px">
                    <span  class="glyphicon glyphicon-big glyphicon-plus" aria-hidden="true"></span>
                </button>
我更改可观察数据的方式:

function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
 self.AddScoreToOpponentTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        taskHub.server.updateLiveScore(self.matchModel());
    }
var url = 'api/MainPage/GetMatchById?matchId=' + matchId;

$.post(url,
    function (data) {
        model.livematch(data);
        console.log(data);
        model.matchModel(toKnockOutObservable(data));
    }, 'json');

ko.applyBindings(model, document.getElementById("livematch"));
function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        var teamScore = self.matchModel().TeamScore();  // Teamscore is 0 (OK)
        teamScore += 1;
        self.matchModel().TeamScore(teamScore);
        taskHub.server.updateLiveScore(self.matchModel()); // When passed to back-end TeamScore property is still 0 (WRONG).
        console.log("Ny teamscore verdi i modellen " + self.matchModel().TeamScore()); // Teamscore is now 1 (OK)
    }
<!--ko with: matchModel-->
    <%--// HOME TEAM--%>
    <div class="col-sm-12">
        <div class="widget-container row">
            <div class="col-sm-12 widget-box">
                <div class="widget-content scrollable visible">
                    <div class="header">
                        <p>
                            <!--ko text: TeamName-->
                            <!--/ko-->
                        </p>
                        <p>
                            <img src="Content/Images/liveupdate.gif" />
                        </p>
                    </div>
                    <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10">
                        <h1><!--ko text: TeamScore--><!--/ko--></h1>
                    </div>
                    <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2">
                <button data-bind="click: $parent.AddScoreToHomeTeam" type="button" class="btn btn-primary btn-lg" id="team_plus" style="width: 100%; height:100px">
                    <span  class="glyphicon glyphicon-big glyphicon-plus" aria-hidden="true"></span>
                </button>
问题:

淘汰模型在UI中更新,一切看起来都很好,但是。。。当我将可观察对象传递给服务器时,它一点也没有改变。。(matchModel与首次加载时相同)

更新可观察对象上的可观察属性的代码:self.matchModel().TeamScore(self.matchModel().TeamScore()+1)

所以。。。我到底做错了什么


更新:09.02.2016:09:15以显示更多代码: 使用it获取数据填充淘汰模型:

function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
 self.AddScoreToOpponentTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        taskHub.server.updateLiveScore(self.matchModel());
    }
var url = 'api/MainPage/GetMatchById?matchId=' + matchId;

$.post(url,
    function (data) {
        model.livematch(data);
        console.log(data);
        model.matchModel(toKnockOutObservable(data));
    }, 'json');

ko.applyBindings(model, document.getElementById("livematch"));
function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        var teamScore = self.matchModel().TeamScore();  // Teamscore is 0 (OK)
        teamScore += 1;
        self.matchModel().TeamScore(teamScore);
        taskHub.server.updateLiveScore(self.matchModel()); // When passed to back-end TeamScore property is still 0 (WRONG).
        console.log("Ny teamscore verdi i modellen " + self.matchModel().TeamScore()); // Teamscore is now 1 (OK)
    }
<!--ko with: matchModel-->
    <%--// HOME TEAM--%>
    <div class="col-sm-12">
        <div class="widget-container row">
            <div class="col-sm-12 widget-box">
                <div class="widget-content scrollable visible">
                    <div class="header">
                        <p>
                            <!--ko text: TeamName-->
                            <!--/ko-->
                        </p>
                        <p>
                            <img src="Content/Images/liveupdate.gif" />
                        </p>
                    </div>
                    <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10">
                        <h1><!--ko text: TeamScore--><!--/ko--></h1>
                    </div>
                    <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2">
                <button data-bind="click: $parent.AddScoreToHomeTeam" type="button" class="btn btn-primary btn-lg" id="team_plus" style="width: 100%; height:100px">
                    <span  class="glyphicon glyphicon-big glyphicon-plus" aria-hidden="true"></span>
                </button>
用数据填充淘汰模型:

function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
 self.AddScoreToOpponentTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        taskHub.server.updateLiveScore(self.matchModel());
    }
var url = 'api/MainPage/GetMatchById?matchId=' + matchId;

$.post(url,
    function (data) {
        model.livematch(data);
        console.log(data);
        model.matchModel(toKnockOutObservable(data));
    }, 'json');

ko.applyBindings(model, document.getElementById("livematch"));
function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        var teamScore = self.matchModel().TeamScore();  // Teamscore is 0 (OK)
        teamScore += 1;
        self.matchModel().TeamScore(teamScore);
        taskHub.server.updateLiveScore(self.matchModel()); // When passed to back-end TeamScore property is still 0 (WRONG).
        console.log("Ny teamscore verdi i modellen " + self.matchModel().TeamScore()); // Teamscore is now 1 (OK)
    }
<!--ko with: matchModel-->
    <%--// HOME TEAM--%>
    <div class="col-sm-12">
        <div class="widget-container row">
            <div class="col-sm-12 widget-box">
                <div class="widget-content scrollable visible">
                    <div class="header">
                        <p>
                            <!--ko text: TeamName-->
                            <!--/ko-->
                        </p>
                        <p>
                            <img src="Content/Images/liveupdate.gif" />
                        </p>
                    </div>
                    <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10">
                        <h1><!--ko text: TeamScore--><!--/ko--></h1>
                    </div>
                    <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2">
                <button data-bind="click: $parent.AddScoreToHomeTeam" type="button" class="btn btn-primary btn-lg" id="team_plus" style="width: 100%; height:100px">
                    <span  class="glyphicon glyphicon-big glyphicon-plus" aria-hidden="true"></span>
                </button>
打开KO视图模型并单击处理程序以修改TeamScore:

function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
 self.AddScoreToOpponentTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        taskHub.server.updateLiveScore(self.matchModel());
    }
var url = 'api/MainPage/GetMatchById?matchId=' + matchId;

$.post(url,
    function (data) {
        model.livematch(data);
        console.log(data);
        model.matchModel(toKnockOutObservable(data));
    }, 'json');

ko.applyBindings(model, document.getElementById("livematch"));
function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        var teamScore = self.matchModel().TeamScore();  // Teamscore is 0 (OK)
        teamScore += 1;
        self.matchModel().TeamScore(teamScore);
        taskHub.server.updateLiveScore(self.matchModel()); // When passed to back-end TeamScore property is still 0 (WRONG).
        console.log("Ny teamscore verdi i modellen " + self.matchModel().TeamScore()); // Teamscore is now 1 (OK)
    }
<!--ko with: matchModel-->
    <%--// HOME TEAM--%>
    <div class="col-sm-12">
        <div class="widget-container row">
            <div class="col-sm-12 widget-box">
                <div class="widget-content scrollable visible">
                    <div class="header">
                        <p>
                            <!--ko text: TeamName-->
                            <!--/ko-->
                        </p>
                        <p>
                            <img src="Content/Images/liveupdate.gif" />
                        </p>
                    </div>
                    <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10">
                        <h1><!--ko text: TeamScore--><!--/ko--></h1>
                    </div>
                    <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2">
                <button data-bind="click: $parent.AddScoreToHomeTeam" type="button" class="btn btn-primary btn-lg" id="team_plus" style="width: 100%; height:100px">
                    <span  class="glyphicon glyphicon-big glyphicon-plus" aria-hidden="true"></span>
                </button>
用户界面中的部分数据绑定(在单击AddScoreToHomeTeam后,该界面起作用并显示正确的TeamScore:

function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
 self.AddScoreToOpponentTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        taskHub.server.updateLiveScore(self.matchModel());
    }
var url = 'api/MainPage/GetMatchById?matchId=' + matchId;

$.post(url,
    function (data) {
        model.livematch(data);
        console.log(data);
        model.matchModel(toKnockOutObservable(data));
    }, 'json');

ko.applyBindings(model, document.getElementById("livematch"));
function toKnockOutObservable(data) {
    return {
        Id: data.Id,
        TeamId: data.TeamId,
        TeamName: data.TeamName,
        OpponentName: data.OpponentName,
        LocationName: data.LocationName,
        MatchDate: data.MatchDate,
        LiveScoreActivated: data.LiveScoreActivated,
        TeamScore: ko.observable(data.TeamScore),
        OpponentScore: ko.observable(data.OpponentScore)
    };
}
var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        var teamScore = self.matchModel().TeamScore();  // Teamscore is 0 (OK)
        teamScore += 1;
        self.matchModel().TeamScore(teamScore);
        taskHub.server.updateLiveScore(self.matchModel()); // When passed to back-end TeamScore property is still 0 (WRONG).
        console.log("Ny teamscore verdi i modellen " + self.matchModel().TeamScore()); // Teamscore is now 1 (OK)
    }
<!--ko with: matchModel-->
    <%--// HOME TEAM--%>
    <div class="col-sm-12">
        <div class="widget-container row">
            <div class="col-sm-12 widget-box">
                <div class="widget-content scrollable visible">
                    <div class="header">
                        <p>
                            <!--ko text: TeamName-->
                            <!--/ko-->
                        </p>
                        <p>
                            <img src="Content/Images/liveupdate.gif" />
                        </p>
                    </div>
                    <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10">
                        <h1><!--ko text: TeamScore--><!--/ko--></h1>
                    </div>
                    <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2">
                <button data-bind="click: $parent.AddScoreToHomeTeam" type="button" class="btn btn-primary btn-lg" id="team_plus" style="width: 100%; height:100px">
                    <span  class="glyphicon glyphicon-big glyphicon-plus" aria-hidden="true"></span>
                </button>
MatchWidget类(viewmodel后端)

我现在唯一能想到的是……是否存在数据类型不匹配或导致这种情况的原因


它们被指定为int的后端..想法?

好的..这里问题的解决方案很容易,但是..很难找到,因为关于这个主题的文档不容易理解

就像理解古埃及的象形文字一样

问题是…一个具有可观察属性的可观察对象由包含您更改的新值的函数组成..在我的例子中..TeamScore

无论您如何通过浏览器调试console.log和debug,这一切似乎都是正确的。但是……当您将可观察对象传递给服务器时……您将无法获得更新的数据,因为这是基于函数的(这……是可观察对象内的可观察属性)

因此…在阅读文档中关于序列化和反序列化的内容时,我了解到我需要在将对象发送到服务器之前对其进行序列化,因为值..存储在可观察函数中

下面的代码示例为我解决了这个问题:

var LiveMatchViewModel = function() {
    var self = this;
    self.livematch = ko.observable();
    self.matchModel = ko.observable();

    self.AddScoreToHomeTeam = function () {
        self.matchModel().TeamScore(self.matchModel().TeamScore() + 1);
        var data = ko.toJSON(self.matchModel());
        taskHub.server.updateLiveScore(data);
    }
请注意ko.toJSON(self.matchModel())

这将序列化并将更改后的观察值存储回对象,生成JSON,并且可以很容易地作为JSON字符串传递回服务器


瞧!…问题解决了…

这是异步javascript,所以self.matchModel()在调用updateLiveScore中将其传回服务器之前,可能无法更新。请尝试使用函数回调。
updateLiveScore
是否需要普通javascript对象?您可以尝试映射发送到更新方法
ko.mapping.toJS(self.matchModel)的数据
另外,仅供参考-如果你只要求
TeamScore
OpponentScore
是可观察的,那么将matchModel设置为可观察的对象对你没有任何好处。你只需将其设置为一个具有相同结果的普通javascript对象即可。你发布的代码在我看来没有问题。请更新问题,并包含足够的代码,以重现e问题。更新了更完整的代码@Jeroen:)