2016-08-23 1 views
0

Ниже приведен очень упрощенный вариант моего кода ..Добавление и удаление объекта из массива, когда наблюдаемый создан из knockout.mapping

Мой HTML-код:

<div class="container body-content" data-bind="foreach:base"> 
    <div class="col-md-12" data-bind="with:s"> 
     <div class="col-md-4"><pre data-bind="text:sp"></pre></div> 
     <div class="col-md-7"> 
      <div class="row" data-bind="foreach: spd"> 
       <input type="text" class="form-control" data-bind="value:value, valueUpdate: 'input'" /> 
       <button data-bind="click: $parent.addval">add</button><button data-bind="click: $parent.removeval">rem</button> 
      </div> 
     </div> 
    </div> 
</div> 

Мой Javascript код:

<script src="knockout-3.2.0.js"></script> 
      <script src="knockout.mapping.js"></script> 
      <script> 
       var data = [{ 
        "s": { 
         "sp": "abc", 
         "spd": [ 
          { 
           "value": "" 
          } 
         ] 
        }, 
        "type": "xyz", 
       }]; 
       var AppScope = function() { 

        function BaseViewModel() { 
         var self = this; 
         self.base = ko.observableArray(); 
         self.base(ko.mapping.fromJS(data)()); 
        } 
        ko.applyBindings(new BaseViewModel()); 
       }(); 
      </script> 

Массив «данных» поступает с сервера и имеет сложную структуру данных, поэтому $ root не может быть использован. Возможно, этот стиль использован here.

Код работает, за исключением кнопок. Я хотел бы понять, как добавить объект {value: ""} к массиву в 'spd' и удалить его при нажатии addval и remval.

Вся помощь искренне оценили Спасибо

ответ

0

Это своего рода странные настройки, но я просто хочу с тем, что вы предоставили. Сначала spd имеет один элемент с пустым значением. Поле ввода позволяет вам изменить значение. Кнопка add дублирует значение в новую запись. Кнопка remove удаляет текущую запись.

Самый сложный бит вычисляет структуру от self.base до spd наблюдаемого массива. Обновление: я изменил обработчики привязки кликов, чтобы принять контекст s (который равен $parent), чтобы они знали, с какими spd они работают.

Я изменил контекст от $parent к $root, потому что это не имеет смысла для меня, чтобы создать addval и removeval функции на s уровне.

var data = [{ 
 
    "s": { 
 
    "sp": "abc", 
 
    "spd": [{ 
 
     "value": "" 
 
    }] 
 
    }, 
 
    "type": "xyz", 
 
}]; 
 
var AppScope = function() { 
 

 
    function BaseViewModel() { 
 
    var self = this; 
 
    self.base = ko.observableArray(); 
 
    self.base(ko.mapping.fromJS(data)()); 
 
    self.addval = function(sData, data) { 
 
     sData.spd.push({value: ko.observable(data.value())}); 
 
    }; 
 
    self.removeval = function(sData, data) { 
 
     sData.spd.remove(data); 
 
    } 
 

 
    } 
 
    ko.applyBindings(new BaseViewModel()); 
 
}();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 
<div class="container body-content" data-bind="foreach:base"> 
 
    <div class="col-md-12" data-bind="with:s"> 
 
    <div class="col-md-4"><pre data-bind="text:sp"></pre> 
 
    </div> 
 
    <div class="col-md-7"> 
 
     <div class="row" data-bind="foreach: spd"> 
 
     <input type="text" class="form-control" data-bind="value:value, valueUpdate: 'input'" /> 
 
     <button data-bind="click: (data) => $root.addval($parent, data)">add</button> 
 
     <button data-bind="click: (data) => $root.removeval($parent, data)">rem</button> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</div>

Если вы хотите, чтобы сделать нечто подобное с помощью ненавязчивого обработки событий (и у вас есть JQuery), соответствующий код может выглядеть следующим образом:

function BaseViewModel() { 
    var self = this; 
    self.base = ko.observableArray(); 
    self.base(ko.mapping.fromJS(data)()); 
    } 
    ko.applyBindings(new BaseViewModel()); 

    $('body').on('click', '.add-btn', function() { 
    const context = ko.contextFor(this); 
    const data = ko.dataFor(this); 
    const s = context.$parent; 

    s.spd.push({ 
     value: ko.observable(data.value()) 
    }); 
    }); 

    $('body').on('click', '.remove-btn', function() { 
    const context = ko.contextFor(this); 
    const data = ko.dataFor(this); 
    const s = context.$parent; 

    s.spd.remove(data); 
    }); 
+0

Спасибо, но не будет работать. У моего массива данных есть несколько объектов, я только что привел один здесь, чтобы показать структуру данных. Также фактический объект, поступающий с сервера, имеет сложную структуру данных, поэтому не может использовать $ root. Кое-что вроде http://knockoutjs.com/documentation/unobtrusive-event-handling.html должно быть использовано, но, к сожалению, неспособно выяснить. – Arnab

+1

Как насчет сейчас? Обработчики кликов передают '$ parent' (который' s', исходящий из 'with' binding) и элемент данных в' addval' и 'removeval'. –

 Смежные вопросы

  • Нет связанных вопросов^_^