Knockout映射和foreach数据绑定在表上的按钮,缺少对viewmodel的引用?

时间:2013-04-09 09:00:28

标签: javascript asp.net-mvc-4 reference knockout.js knockout-mapping-plugin

我使用mvc4和entityframework结合淘汰赛。我也使用淘汰赛映射。但是我遇到了一个无法解决的问题。

我想要实现的目标:

  • 用户点击删除按钮删除表格中的行。 [作品
  • 调用mvc控制器上的delete action方法以实际删除数据 数据库。 [作品
  • 发回包含新更改数据的新Json对象 表。 [作品
  • 在我的基质视图模型中加载新数据并使用ko.mapping.fromJS() and ko.applyBindings()更新用户界面 [不会 工作,我真的迷失在这里]

看起来我完全失去了对我的经验列表的引用,这些经验用于数据绑定和foreach我的表。而且我认为这与我在foreach循环中调用deletemethod的方式有关。

看起来像var self = this;的javascript'技巧'无法获取我对正确数据的引用。

以下是我现在使用的代码,可以让您更好地了解情况。如果需要更多信息,请告诉我。

这些是我的mvc viewmodels:

public class ExperienceOverviewModel
{
        public ExperienceModel selectedExperience { get; set; }
        public List<ExperienceModel> Experiences { get; set; }
}

public class ExperienceModel
{
        public int ExperienceId { get; set; }
        public DateTime DateFrom { get; set; }
        public DateTime DateUntil { get; set; }
        public string Description { get; set; }
        public string Employer { get; set; }
        public decimal Hours { get; set; }
        public int PersonId { get; set; }
        public bool? Secondment { get; set; }
        public string Title { get; set; }
}

这是我的表格,我在这里使用淘汰赛来描述经验:

</table>
    <thead>
        </thead> 
    <tbody data-bind="foreach: Experiences()">
            <tr>
                <td data-bind="text: Employer"></td>
                <td data-bind="text: Description"></td>
                <td data-bind="text: DateFrom"></td>
                <td data-bind="text: DateUntil"></td>
                <td data-bind="text: Secondment"></td>
                <td>
                    <a href="#" data-bind="click: function(data, event){ $root.EditExperienceModal(data); }"><i class="icon-edit"></i></a>
                </td>
                <td>
                    <a href="#" data-bind="click: function(data, event){ $root.ConfirmDeleteExperienceModal(data);}"><i class="icon-remove"></i></a>
                </td>
            </tr>
        </tbody>
    </table>

我的淘汰视图模型,我想调用ko.mapping.fromJS()和ko.applyBindings()......这就是fubar ....

    function ViewModel() {
            this.DeleteExperience = function (experience) {

                $.ajax({
                    type: "post",
                    contentType: "application/json",
                    url: "/Experienced/Delete/" + this.selectedExperience.ExperienceId(),
                    data: ko.toJSON(self.selectedExperience),
                    error: function (xhr, status, error) {
                    },
                    success: function (response) {

                        ko.mapping.fromJS(response, ?? this.Experiences ??);  <---- ???
                        ko.applyBindings(?????);                              <---- ???

                    }
                });
            }
        }

        $(function () {
            var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
            var mvcModel = ko.mapping.fromJSON(jsonModel);

            var myViewModel = new ViewModel();
            g = ko.mapping.fromJS(myViewModel, mvcModel);
            ko.applyBindings(g);
        });

* - 更新 - *

为了澄清更多,我在这里简单说明了: 当我从AJAX调用中得到结果时,我收到以下错误:

  

对象#没有方法'经验'

<table class="table table-striped">
    <tbody data-bind="foreach: Experiences()">
        <tr>
            <td data-bind="text: Employer"></td>
            <td data-bind="text: Description"></td>
            <td data-bind="text: DateFrom"></td>
            <td data-bind="text: DateUntill"></td>
            <td data-bind="text: Secondment"></td>
            <td>
               <a href="#" data-bind="click: $root.DeleteExperience"><i class="icon-remove"></i></a>

            </td>
        </tr>
    </tbody>
</table>
<script type="text/javascript">

    function ViewModel() {
        var self = this;

        self.DeleteExperience = function (experience) {
            $.ajax({
                type: "post",
                contentType: "application/json",
                url: "/Experienced/Delete/" + experience.ExperienceId(),
                data: ko.toJSON(experience),
                error: function (xhr, status, error) {
                    console.log(error);
                },
                success: function (response) {
                    $('#confirmDeleteModal').modal('hide');
                    self.UpdateExperienceList(response);
                }
            });
        }

        self.UpdateExperienceList = function (data) {
            self.Experiences(data);       <---- ?????
        }
    }

    $(function () {
        var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
        var mvcModel = ko.mapping.fromJSON(jsonModel);
        var myViewModel = new ViewModel();
        g = ko.mapping.fromJS(myViewModel, mvcModel);
        ko.applyBindings(g);
    });
</script>

2 个答案:

答案 0 :(得分:0)

我认为您不需要再次致电ko.applyBindings(?????);。您应该明确定义视图模型:

function MyModel() {
    var self = this;

    self.Data = ko.observableArray([{"Name": "Lionel Messi", "Occupation": "Football player"}, {"Name": "Jason Mraz", "Occupation": "Singer"}, {"Name": "Nicolas Cage", "Occupation": "Film Actor"}]);

    self.update = function(data) {
        self.Data(data);
    }
}

$(function(){
    var model = new MyModel();
    ko.applyBindings(model);
});

如您所见,我定义self.update,您只需调用此函数并更新您的数据,如果您想从表中删除一行,您只需splice self.Data()行}

答案 1 :(得分:0)

self.UpdateExperienceList功能中,尝试以下操作:

self.UpdateExperienceList = function(data) {
    ko.mapping.fromJSON(data, {}, self);
};

这将根据来自服务器的数据更新self对象的属性。

您最初创建视图模型对我来说也是错误的。我想你会想要更像下面的东西:

var myViewModel = ko.mapping.fromJSON(jsonModel, {}, new ViewModel());