Нокаут картографиране и foreach data-bind върху таблица с бутони, липсва препратка към viewmodel?

Използвам mvc4 и entityframework в комбинация с нокаут. Аз също използвам knockout mapping. Но се натъквам на проблем, който не мога да разреша.

Какво искам да постигна:

  • Потребителят щраква върху бутона за изтриване, за да изтрие ред от таблицата. [Работи]
  • Извикайте метода за действие за изтриване на mvc контролера, за да изтриете данните от базата данни. [Работи]
  • Изпратете обратно нов Json обект, съдържащ данните от новата променена таблица. [Работи]
  • Заредете новите данни в моя нокаут модел на изглед и актуализирайте потребителския интерфейс с помощта на ko.mapping.fromJS() and ko.applyBindings() [Не работи и наистина съм изгубен тук]

Изглежда, че напълно съм загубил препратката към моя списък с опит, който използвам за свързване на данни и foreach на моята таблица. И мисля, че това е свързано с начина, по който извиквам моя метод за изтриване от цикъла foreach.

Изглежда също така, че „трикът“ на javascript с var self = this; не работи, за да получа препратката ми към правилните данни.

Ето моя код, който използвам за момента, за да ви дам по-добра представа за ситуацията. Ако е необходима повече информация, моля, уведомете ме.

Това са моите 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 databind изживяванията с нокаут:

</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="/bg#" data-bind="click: function(data, event){ $root.EditExperienceModal(data); }"><i class="icon-edit"></i></a>
                </td>
                <td>
                    <a href="/bg#" 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="/bg#" 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>

person user1853542    schedule 09.04.2013    source източник
comment
Можете ли да публикувате кода, който дефинира this.Experiences? Почти сигурно обаче няма да можете да използвате this. тук - обектът this във вашето обратно извикване success не е същият, както е във вашата функция ViewModel...   -  person Steve Greatrex    schedule 09.04.2013
comment
Благодаря, но все още имам същия проблем, актуализирах въпроса си, за да направя проблема по-ясен.   -  person user1853542    schedule 09.04.2013
comment
Къде създавате self.Experiences?   -  person Steve Greatrex    schedule 09.04.2013
comment
self.Experiences идва от моя mvc4 viewmodel. то се картографира към нокаут. на този ред var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';   -  person user1853542    schedule 09.04.2013


Отговори (2)


Във вашата функция self.UpdateExperienceList опитайте следното:

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

Това ще актуализира свойствата на обекта self въз основа на данните от сървъра.

Вашето първоначално създаване на модела на изглед също ми изглежда грешно. Бих искал да искаш нещо по-подобно на следното:

var myViewModel = ko.mapping.fromJSON(jsonModel, {}, new ViewModel());
person Steve Greatrex    schedule 09.04.2013
comment
Благодаря ти! Знам, че инициализирам всичко с: var myViewModel = ko.mapping.fromJSON(jsonModel, {}, new ViewModel()); и self.UpdateExperienceList = функция (данни) {ko.mapping.fromJSON(данни, {}, self.Experiences); } Най-накрая работи! Благодаря! - person user1853542; 09.04.2013

Не мисля, че трябва да звъниш на 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()

person Phong Vo    schedule 09.04.2013
comment
Благодаря за приноса ви, но това няма решение, актуализирах първоначалния си въпрос, за да опростя проблема си - person user1853542; 09.04.2013