【问题标题】:Knockout Mapping Observable Array MVCKnockout Mapping Observable Array MVC
【发布时间】:2013-04-22 15:27:27
【问题描述】:

您好,我在网上找了几个小时试图解决这个问题,但找不到解决方案。

我正在使用 ASP.NET MVC 和 Knockout 构建解决方案。控制器将用户选择的选项返回给视图,视图将其转换为 JSON,并使用映射插件将其映射到淘汰视图模型。它会正确填充,因为当我这样做时: ko.toJSON($data) 来测试它,会返回正确的数据,但是当添加项目时视图不会更新列表。

我的猜测是这些属性不是可观察的,但我不确定如何解决这个问题。

这是返回的 JSON 示例:

[{"Key":1,"Value":"company"}]

这是我的javascript:

function ProjectWorkedOn() {
    var self = this;
    self.client = ko.observable();
    self.job = ko.observable();
    self.project = ko.observable();
    self.workType = ko.observable();
}

function createTimesheetViewModel() {
    var self = this;

    //list of options
    self.UserClients = ko.observableArray();
    self.UserProjects = ko.observableArray();
    self.UserJobs = ko.observableArray();
    self.UserWorkTypes = ko.observableArray();

    //keep track of selected options
    self.selectedClient = ko.observable();
    self.selectedProject = ko.observable();
    self.selectedJob = ko.observable();
    self.selectedWorkType = ko.observable();

    //list to add choices in
    self.ListProjectsWorkedOn = ko.observableArray();


    self.addProjectWorkedOn = function () {
        var project = new ProjectWorkedOn();
        project.client = self.selectedClient;
        project.job = self.selectedJob;
        project.project = self.selectedProject;
        project.workType = self.selectedWorkType;
        self.ListProjectsWorkedOn.push(project)
    }
    self.removeProjectWorkedOn = function (projectWorkedOn) {
        self.ListProjectsWorkedOn.remove(projectWorkedOn)
    }

}



$(function () {
    var CreateTimesheetViewModel = new createTimesheetViewModel();

    CreateTimesheetViewModel.UserClients = ko.mapping.fromJSON('@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.UserClients))');
    CreateTimesheetViewModel.UserProjects = ko.mapping.fromJSON('@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.UserProjects))');
    CreateTimesheetViewModel.UserJobs = ko.mapping.fromJSON('@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.UserJobs))');
    CreateTimesheetViewModel.UserWorkTypes = ko.mapping.fromJSON('@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.UserWorkTypes))');

    ko.applyBindings(CreateTimesheetViewModel, document.getElementById("CreateTimesheet"));
});

这是将项目添加到列表的视图部分:

<table>
    <tr>
        <td>
            Projects Worked On:
        </td>
        <td>
            Client: <select data-bind="options: UserClients, optionsText: 'Value', value: selectedClient"></select>
        </td>
        <td>
            Project: <select data-bind="options: UserProjects, optionsText: 'Value', value: selectedProject"></select>
        </td>
        <td>
            Job: <select data-bind="options: UserJobs, optionsText: 'Value', value: selectedJob"></select>
        </td>
        <td>
            Service: <select data-bind="options: UserWorkTypes, optionsText: 'Value', value: selectedWorkType"></select>
        </td>
        <td>
            <button data-bind="click: addProjectWorkedOn">Add Project</button>
        </td>
    </tr>
</table>

这就是显示它们的内容:

<table>
    <tr>
        <td>Client</td>
        <td>Project</td>
        <td>Job</td>
        <td>Service</td>
        <td></td>
    </tr>
    <tbody data-bind="foreach: ListProjectsWorkedOn()">
        <tr>
            <td data-bind="text: client.Value"></td>
            <td data-bind="text: project.Value"></td>
            <td data-bind="text: job.Value"></td>
            <td data-bind="text: workType.Value"></td>
            <td><button data-bind="click: $parent.removeProjectWorkedOn">Remove</button></td>
        </tr>
    </tbody>
</table>

提前致谢!

编辑:

我解决了

要添加项目,请设置如下属性:project.clientValue(self.selectedClient().Value);

然后在视图中引用它们作为函数调用:clientValue()

感谢 Chris Patt 解释说,当你想获得 observables 的价值时,应该将其作为函数调用

【问题讨论】:

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


    【解决方案1】:

    因为您设置了 ProjectWorkedOn 可观察对象并错误地获取了所选值。要设置一个可观察对象,您可以像传递函数一样将值作为参数传递,而要获取可观察对象的值,您可以像调用函数一样调用它。 (它们实际上是函数。):

    self.addProjectWorkedOn = function () {
        var project = new ProjectWorkedOn();
        project.client(self.selectedClient());
        project.job(self.selectedJob());
        project.project(self.selectedProject());
        project.workType(self.selectedWorkType());
        self.ListProjectsWorkedOn.push(project)
    }
    

    编辑

    我认为您确实想要选择的值,而不是实际的整个 JSON 对象。你正在尝试的根本是不可能的。 select 的值必须是整数或字符串——它不能是完整的对象。通常你会通过首先简单地返回一个值/文本列表来填充选择来处理这样的事情,其中​​的值类似于 id。然后,在选择后,您将发出 AJAX 请求以检索具有该 ID 的对象。

    【讨论】:

    • 谢谢,我试过了,但它仍然没有显示值。该列表正在显示并且它的大小正在增加,但它绑定到的每个值都是空的。
    • 奇怪的是我可以添加和删除但它不会显示数据
    • 我只是将其更改为键值对,但无论哪种方式,它似乎都应该工作,因为在我添加新项目时正在填充列表。唯一的问题是它不会更新绑定到它的视图部分。
    • 您确实将新的ProjectWorkOns 添加到 observableArray,但没有有意义的数据进入对象。
    猜你喜欢
    • 2017-12-13
    • 2013-03-14
    • 1970-01-01
    • 2014-10-01
    • 2014-11-27
    • 2013-03-11
    • 2013-11-10
    • 2012-06-14
    • 2015-10-25
    相关资源
    最近更新 更多