带有按钮的表格上的敲除映射和 foreach 数据绑定,缺少对视图模型的引用?

Posted

技术标签:

【中文标题】带有按钮的表格上的敲除映射和 foreach 数据绑定,缺少对视图模型的引用?【英文标题】:Knockout mapping and foreach data-bind on table with buttons, missing reference to viewmodel? 【发布时间】:2013-03-31 15:05:16 【问题描述】:

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

我想要达到的目标:

用户单击删除按钮从表中删除行。 [作品] 在 mvc 控制器上调用 delete 操作方法来实际删除数据 数据库。 [作品] 发回包含新更改数据的新 Json 对象 桌子。 [作品] 在我的淘汰视图模型中加载新数据并使用ko.mapping.fromJS() and ko.applyBindings() 更新 UI [不 工作,我真的迷路了]

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

看起来带有 var self = this;javascript“技巧”也无法让我引用正确的数据。

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

这些是我的 mvc 视图模型:

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; 

这是我使用淘汰赛 foreach 数据绑定经验的表格:

</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>

【问题讨论】:

你能贴出定义this.Experiences的代码吗?不过,您几乎肯定不能在这里使用this. - 您的success 回调中的this 对象与您的ViewModel 函数中的对象不同... 谢谢,但我仍然有同样的问题,我更新了我的问题以使问题更清楚。 你在哪里实例化self.Experiences self.Experiences 来自我的 mvc4 视图模型。它被映射到淘汰赛。在这一行 var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))'; 【参考方案1】:

在您的 self.UpdateExperienceList 函数中,尝试以下操作:

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

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

您最初创建的视图模型在我看来也是错误的。虽然你想要更像下面的东西,但我会想要的:

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

【讨论】:

谢谢!我知道用以下方法初始化一切: var myViewModel = ko.mapping.fromJSON(jsonModel, , new ViewModel());和 self.UpdateExperienceList = function (data) ko.mapping.fromJSON(data, , self.Experiences);终于成功了!谢谢!【参考方案2】:

我认为您无需再次致电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,您只需调用此函数并更新您的数据,如果您想从表中删除一行,您只需 spliceself.Data() 中的那一行

【讨论】:

感谢您的意见,但没有解决方案,我已更新我的原始问题以简化我的问题

以上是关于带有按钮的表格上的敲除映射和 foreach 数据绑定,缺少对视图模型的引用?的主要内容,如果未能解决你的问题,请参考以下文章

Bootstrap 切换按钮的敲除绑定

具有“只读”和“禁用”等属性的敲除 attr 绑定

外部组件的敲除和要求

输入按键的敲除事件绑定导致奇怪的行为

使用 Jquery 加载填充 jquery ui 对话框时的敲除绑定

如何在敲除时在 foreach 循环中绑定输入值