Knou.js получает модель из сопоставления сервера с помощью плагина сопоставления и отправляет модель обратно

Я начал использовать Knockout.js, и мне это очень нравится. Я использую ASP.Net mvc, jQuery и Knockout.js.

Мой вопрос таков: скажем, у меня есть экран управления пользователем, пользователь - это моя модель просмотра внутри пользователя, мне нужен массив разрешений

мой пользовательский видМодель:

var userViewModelClass = function () {
   var self = this;
   ko.mapping.fromJS({
       ID: "",
       permissions: []
   }, {}, self);
}

теперь .. если я делаю ajax-запрос на сервер и получаю обратно JSON, я использую плагин сопоставления, и все идет так, как ожидалось

но... теперь я хочу, чтобы в моем отображаемом списке разрешений было такое действие, как удаление. поэтому мне понадобится объект разрешений, а затем массив разрешений будет массивом объектов разрешений. но как мне это сделать? как плагин сопоставления узнает, что объект, возвращенный ему с сервера в массиве, на самом деле находится в таком объекте, как этот:

 function permission() {
   var self = this;
   this.delete = function () {       
   };
   ko.mapping.fromJS({
       name: "",
       level: ""
    }, {}, self);
}

это моя первая часть вопроса. вторая часть: скажем, я получил модель с массивом всех разрешений, и все они являются объектом этого разрешения. теперь я хочу, чтобы каждая кнопка удаления в моем представлении была привязана к функции удаления внутри объекта разрешения. с использованием:

data-bind="click: delete"

какова наилучшая реализация функции удаления? Я подумал о чем-то вроде: сделать ajax-вызов на сервер, который фактически удалит разрешение пользователя. затем, если вызов будет успешным, удалите текущее разрешение из наблюдаемого массива, тогда представление будет обновлено... это хорошая практика?

Спасибо!


person guy schaller    schedule 14.06.2012    source источник


Ответы (1)


Первая часть. Вам нужно использовать параметры сопоставления. В своем userViewModelClass сделайте это.

var userViewModelClass = function () {
   var self = this;
   ko.mapping.fromJS({
       ID: "",
       permissions: []
   }, {
       permissions: {
           create: function(options) {
               return new permission(options.data);
           }
       }
   }, self);
}

И измените свой объект разрешений так

function permission(config) {
   var self = this;
   this.delete = function () {       
   };
   ko.mapping.fromJS($.extend({
       name: "",
       level: ""
    }, config), {}, self);
}

Примечание. Я добавил расширение, чтобы ваша структура по умолчанию оставалась и перезаписывалась входящими данными.

Вторая часть вашего вопроса. Одним из возможных способов было бы передать ссылку на родителя в вашем конструкторе. Таким образом, приведенные выше параметры отображения станут

permissions: {
    create: function(options) {
        return new permission(options.data, self);
    }
}

Тогда ваше удаление может быть чем-то вроде.

this.delete = function () {  
    $.ajax(deleteurl, yourdata, function(result) {
       // success
       parent.permissions.remove(self);
    }, function() {
       // failure
       display error message
    }     
};

ИЗМЕНИТЬ

Альтернативный способ, как обсуждалось в комментариях.

var userViewModelClass = function () {
   var self = this;
   ko.mapping.fromJS({
       ID: "",
       permissions: []
   }, {
       permissions: {
           create: function(options) {
               return new permission(options.data);
           }
       }
   }, self);

   this.delete = function(permission) {
       self.permissions.remove(permission);
   };
}

data-bind="click: $parent.delete"

Надеюсь это поможет.

person madcapnmckay    schedule 14.06.2012
comment
спасибо, я скоро попробую и вернусь сюда :), я понимаю первую часть, и это выглядит красиво. но мне не понравилась вторая часть.. подумайте об этом, у вас есть объект, содержащий объект, и этот второй объект будет иметь ссылку на своего отца?.. и тогда у вас есть эта строка: parent.permissions.remove(self ); вы переходите к родителю, затем к коллекции, в которой находитесь, а затем удаляете себя. мне кажется странным... я понимаю, что это сработает, но все равно странно. я думаю, чего ему не хватает, так это событий - person guy schaller; 15.06.2012
comment
Я просто показывал вам способ сделать это с помощью простого js, как вы его изложили. На мой взгляд, удаление должно быть членом родительского, а не дочернего элемента. Таким образом, ваш метод удаления должен быть в классе userViewModel. События слишком усложняют ситуацию в этом тривиальном сценарии. - person madcapnmckay; 15.06.2012
comment
большое спасибо! не знал об этом: $parent.delete да, это, безусловно, ответ на мой вопрос, а также отлично выглядит. Спасибо - person guy schaller; 15.06.2012