0

Я изо всех сил пытаюсь создать интерактивную форму, в которой в viewmodel есть коллекция предметов. Я хочу динамически добавить/удалить элементов из этой коллекции.Добавить и удалить Элементы на стороне клиента с помощью Knockoutjs

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

var company; 

function PersonViewModel(data) { 
    var personMapping = { 
    'ignore': ['twitter', 'webpage'], 
    'copy': ['age'], 
    'lastName': { 
     'create': function (options) { 
     return ko.observable(options.data.toUpperCase()); 
     } 
    } 
    }; 

    ko.mapping.fromJS(data, personMapping, this); 

    this.fullName = ko.computed(function() { 
    return this.firstName() + ' ' + this.lastName(); 
    }, this); 
} 

function CompanyViewModel(data) { 
    var companyMapping = { 
    'ignore': ['address', 'website'], 
    'name': { 
     'create': function (options) { 
     return ko.observable(options.data.toUpperCase()); 
     } 
    }, 
    'employees': { 
     key: function (data) { 
     return ko.utils.unwrapObservable(data.personId); 
     }, 
     create: function (options) { 
     return new PersonViewModel(options.data); 
     } 
    } 
    }; 

    ko.mapping.fromJS(data, companyMapping, this); 
} 

Что я не знаю, как достичь в , как и где точно добавить «addEmployee» и функции «» removeEmployee? и как связать их с кнопкой ?.

Спасибо заранее!

+0

Так как представляется, компания, которая владеет сотрудников, я думаю, что VM будет логичным местом для добавления и удаления функций. Затем вы добавляете и удаляете кнопки, привязанные к этим функциям. Без дополнительного контекста трудно дать полный ответ. –

ответ

1

Логическое место, чтобы добавить их бы к вашему CompanyViewModel. Например, что-то вроде этого:

function CompanyViewModel(data) { 
    var self = this; 
    var companyMapping = { 
    // ...as before 
    }; 

    self.addEmployee = function() { 
    // as an example, we are just adding a static new employee 
    self.employees.push(new PersonViewModel({ 
     lastName: "new", 
     firstName: "employee", 
     age: 10 
    })); 
    } 

    // important, with how we are binding the function, we expect the 
    // argument, e, to be the employee to remove 
    self.removeEmployee = function (e) { 
    self.employees.remove(e); 
    } 

    ko.mapping.fromJS(data, companyMapping, this); 
} 

Добавить связать, вы можете сделать что-то вроде этого:

<div id="company"> 
    <h1 data-bind="text: name"></h1> 
    <h2>Employees</h2> 
    <input type="button" value="add" data-bind="click: addEmployee" /> 
    <table> 
    <thead> 
     <tr> 
     <th>Full name</th> 
     <th>Last name</th> 
     <th>First name</th> 
     <th>Age</th> 
     </tr> 
    </thead> 
    <tbody data-bind="foreach: employees"> 
     <tr> 
     <td data-bind="text: fullName"></td> 
     <td data-bind="text: lastName"></td> 
     <td data-bind="text: firstName"></td> 
     <td data-bind="text: age"></td> 
     <td> 
      <input type="button" value="x" data-bind="click: $parent.removeEmployee" /> 
     </td> 
     </tr> 
    </tbody> 
    </table> 
</div> 

Что добавит add кнопку, а также Вытащите x кнопку для каждого сотрудника, который вызывает функция removeEmployee на родительском CompanyViewModel, проходящей в текущем сотруднике.

Вот обновленный fiddle

+0

Спасибо, он работает так, как я хотел, всего пару вопросов сейчас, это идеальный способ сделать это, когда вам нужно добавлять предметы к дочернему объекту? и во-вторых, мне непонятно, почему ko.applyBindings используется так много раз (в 3 раза) – randomguy04

+0

Во-первых, 'это идеальный способ сделать это, когда вам нужно добавлять элементы к дочернему объекту? не единственный способ, но это было бы так, как это делали бы большинство людей.Вы работаете в коллекции, принадлежащей 'CompanyViewModel', поэтому имеет смысл, что эти функции будут * принадлежать * к' CompanyViewModel'. Во-вторых, я вижу только один «ko.applyBindings». –

+0

Извините, я имел в виду, ko.mapping.fromJS вместо ko.applyBindings, я думал, что первое должно использоваться только один раз, а также последний. и спасибо! теперь у меня это работает, как хотелось. – randomguy04

0

Вы бы добавили эти функции в ваш CompanyViewModel.

CompanyViewModel

... 
this.addEmployee = function() { 
    this.employees.push(new PersonViewModel({ 
     firstName: 'New', 
     lastName: 'Employee', 
     age: 777, 
    })); 
}; 
this.removeEmployee = function() { 
    this.employees.pop(); 
}; 

HTML

.... 
<div data-bind="click: addEmployee">Add Employee</div> 
<div data-bind="click: removeEmployee">Remove Employee</div> 
... 

http://jsfiddle.net/HBKYP/198/

+0

Здесь нет никакого контроля над тем, какой сотрудник вы удаляете. Вы просто удаляете последнее добавленное – Pogrindis

+0

. Я предполагаю, что они хотят удалить * конкретного * сотрудника, а не просто выскочить последнего добавленного парня. –

+0

Это требование не указано. Вопрос только задал *, где * эти функции должны быть добавлены. – CrimsonChris

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