简体   繁体   中英

Using Knockout for create and update on ViewModel

HTML

<input type="button" id="addNewCert" value="Add New Certification" class="btn btn-primary" data-bind="click: addCert"/>
<table class="table table-striped">
    <thead>
        <tr>
            <th></th>
            <th>Name</th>
            <th>Code</th>
            <th>Description</th>
            <th>Type</th>
        </tr>
    </thead>

    <tbody data-bind="foreach: certs">
        <tr>
            <td><input type="button" class="btn" value="Edit" data-bind="click: $parent.editCert" /></td>
            <td data-bind="text: certName"></td>
            <td data-bind="text: certCode"></td>
            <td data-bind="text: description"></td>
            <td data-bind="text: certTypeName"></td>
        </tr>
    </tbody>
</table>

<div id="selectedCert" data-bind="with: selectedCert">
    <div class="well">
        <div class="row-fluid">
            <div class="span6">
                <div class="control-group">
                    <h6>Certification Name</h6>
                    <input type="text" id="CertificationName" data-bind="value: certName" style="width:100%;" />

                </div>
                <div class="control-group">
                    <h6>Certification Code</h6>
                    <input type="text" id="CertificationCode" data-bind="value: certCode" style="width:50%;" />
                </div>
                <div class="control-group">
                    <h6>Description</h6>
                    <textarea ID="Description" data-bind="value: description" style="height:250px;width:480px;"></textarea>
                </div>
                <div class="control-group">
                    <h6>Certification Type</h6>
                    <select id="CertificationType" data-bind="options: $parent.availableCertTypes, optionsText: 'certTypeName', optionsValue: 'certTypeId', value: $parent.selectedCertType" style="width:100%;"></select>
                </div>

            </div>
        </div>
    </div>
</div>

Model

var Certification = function(data) {
    this.certId = ko.observable(data.CertificationId);
    this.certName = ko.observable(data.CertificationName);
    this.certCode = ko.observable(data.CertificationCode);
    this.description = ko.observable(data.Description);
    this.certTypeId = ko.observable(data.CertTypeId);
    this.certTypeName = ko.observable(data.CertTypeName);
    this.isEditing = ko.observable(false);
}

ViewModel

var certViewModel = function (certs) {

    //Data
    var self = this;
    self.certs = ko.observableArray([]);
    self.editingCert = ko.observable(false);
    self.selectedCert = ko.observable();
    self.availableCertTypes = ko.observableArray([]);
    self.selectedCertType = ko.observable();

    self.editCert = function (cert) {
        self.editingCert(true);
        self.selectedCertType(cert.certTypeId());
        self.selectedCert(cert);
    }

    //Operations
    self.addCert = function () {
        self.selectedCert(new Certification());
    };

    self.removeCert = function (cert) {
        self.certs.remove(cert);
    };

    self.save = function () {

    };
}

I have a grid that is built out with Edit buttons for a list of Certifications, and when the edit button is clicked, the with binding works perfectly and shows me the correct information alongside the correctly selected option in the <select> tag.

The Problem

But now what I am unsure of, is how do I let the button at the very top to "Add New Certification", generate a blank instance of the Certification model and show that same "edit" area?

I have found a ton of examples of doing edits for "inline" binding and edits, but that's not really what I'm going for as I'm trying to learn some of the ins and outs of Knockout and WebAPI to see if I can make a more client-side and AJAX driven version of some modules that are more based on WebForms.

Running your code gives an error because data is undefined when building the model. It may have also been omitted but I don't see the applyBindings call here.

Here is a JSFiddle with it working:

http://jsfiddle.net/jzhh3/

The only changes are:

self.selectedCert(new Certification());

changed to

self.selectedCert(new Certification({}));

And the addition of ko.applyBindings(certViewModel);

You need to be able to call new Certification() without passing it an existing one, so in your constructor for Certification, check if data is null.

http://jsfiddle.net/QG3UZ/1/

var Certification = function(data) {
  this.certId = ko.observable(data ? data.CertificationId : null);
  this.certName = ko.observable(data ? data.CertificationName : null);
  this.certCode = ko.observable(data ? data.CertificationCode : null);
  this.description = ko.observable(data ? data.Description : null);
  this.certTypeId = ko.observable(data ? data.CertTypeId : null);
  this.certTypeName = ko.observable(data ? data.CertTypeName : null);
  this.isEditing = ko.observable(data ? false : true);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM