2013-04-29 65 views
0

嗨我已经在网上查了几个小时试图解决这个问题,但我找不到解决方案。Knockout Mapping可观察阵列MVC

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

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

这是JSON返回的的一个示例:

[{ “密钥”:1, “值”: “公司”}]

这是我的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()值);

然后引用它们考虑把它作为一个功能:clientValue()

归功于克里斯·帕拉特解释,当你想要得到他们的价值是可观应该被称为功能

回答

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的对象。

+0

谢谢,我试过了,但它仍然没有显示值。该列表正在显示,并且它的大小正在增加,但它绑定到的每个值都是空的。 – 2013-04-29 04:02:53

+0

奇怪的是,我可以添加和删除,但它不会显示数据 – 2013-04-29 04:42:36

+0

我只是将它更改为键值对,但无论哪种方式,它似乎应该工作,因为列表正在填充,因为我正在添加新项目。唯一的问题是它不会更新绑定到视图的部分。 – 2013-04-29 05:13:14