javascript - Knockout mapping and foreach data-bind on table with buttons, missing reference to viewmodel? -
i use mvc4 , entityframework in combination knockout. use knockout mapping. run problem wich cannot solved.
what want achieve:
- user clicks on delete button delete row table. [works]
- call delete action method on mvc controller actualy delete data database. [works]
- send new json object containing data of new changed table. [works]
- load new data in knockout viewmodel , update ui using
ko.mapping.fromjs() , ko.applybindings()
[does not work , realy lost here]
it looks totaly lost reference list of experiences wich use databind , foreach table with. , think has way call deletemethod within foreach loop.
it looks javascript 'trick' var self = this;
doesnt work reference correct data.
here follows code use give better idea of situation. if more information needed please let me know.
these 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; } }
this table foreach databind experiences using knockout:
</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>
my knockout viewmodel want call ko.mapping.fromjs() , ko.applybindings()... here goes 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); });
* -- updated -- *
to clarify more here have simplyfied: when results ajax call following error:
object # has no method 'experiences'
<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>
in self.updateexperiencelist
function, try following:
self.updateexperiencelist = function(data) { ko.mapping.fromjson(data, {}, self); };
this update properties on self
object based on data server.
your initial creation of view model looks wrong me. have though wanted more below:
var myviewmodel = ko.mapping.fromjson(jsonmodel, {}, new viewmodel());
Comments
Post a Comment