如何使用knockout js

时间:2015-07-06 08:27:46

标签: javascript jquery asp.net-mvc knockout.js

我正在尝试使用Knockout JS创建一个主细节页面,如下图所示 enter image description here

我有一个问题是从详细信息中获取bootstrap模态的值。例如,在辅助客户端列单击“浏览”按钮后,将在引导模式中显示辅助客户端列表。 enter image description here

单击选择链接后,我无法将值(SubsidiaryClientID,SubsidiaryClientNo和Name)返回到父页面。如何获取这些值并设置为父页面?

以下是代码:

查看:Create.cshtml

<form action="~/Invoice/CreateKO" method="post">
    <div class="form-horizontal">
        <hr />

        <div class="form-group">
            <label class="control-label col-md-2">Office</label>
            <div class="col-md-10">
                <select name="OfficeID" id="OfficeID" class="form-control" data-bind="options: Offices, optionsText: 'Name', optionsValue: 'OfficeID', optionsCaption: '-- Please Select --', value: OfficeID"></select>
            </div>
        </div>

        <div class="form-group">
            <label class="control-label col-md-2">Client</label>
            <div class="col-md-10">
                <input type="hidden" name="ClientID" id="ClientID" data-val-required="The Client field is required."
                       data-val-number="The field Client must be a number." data-val="true" data-bind="value: ClientID" />
                <div class="form-inline">
                    <input type="text" name="ClientName" id="ClientName" readonly="readonly" value="" class="form-control" style="width: 280px" />
                    <button type="button" class="btn btn-primary" data-bind="click: browseClient, enable: OfficeID()">...</button>
                </div>
            </div>
        </div>

        <div class="table-responsive">
            <table class="table table-striped table-hover table-condensed">
                <thead>
                    <tr>
                        <th></th>
                        <th>Subsidiary Client</th>
                        <th>Firm's Matter</th>
                        <th>eBilling Matter</th>
                        <th>Invoice No</th>
                        <th>Attachment</th>
                    </tr>
                </thead>
                <tbody data-bind="foreach: Invoices, visible: Invoices().length > 0">
                    <tr>
                        <td><a href="#" data-bind="click: $parent.removeInvoice">Remove</a></td>
                        <td>
                            <input type="hidden" data-bind="value: SubsidiaryClientID" />
                            <input type="text" class="form-control" data-bind="value: SubsidiaryClientNo" readonly="readonly" />
                            <input type="text" class="form-control" data-bind="value: SubsidiaryClientNo" readonly="readonly" />
                            <button type="button" class="btn btn-primary" data-bind="click: browseSubsidiaryClient">...</button>
                        </td>
                        <td>
                            <input type="text" class="form-control" data-bind="value: FirmMatterNo" readonly="readonly" />
                            <input type="text" class="form-control" data-bind="value: FirmMatterDescription" readonly="readonly" />
                            <input type="text" class="form-control" data-bind="value: FirmMatterLocation" readonly="readonly" />
                            <input type="text" class="form-control" data-bind="value: LocationDescription" readonly="readonly" />
                            <button type="button" class="btn btn-primary" data-bind="click: browseFirmMatter">...</button>
                        </td>
                        <td>
                            <input type="hidden" data-bind="value: ClientMatterID" />
                            <input type="text" class="form-control" data-bind="value: ClientMatterNo" readonly="readonly" />
                            <input type="text" class="form-control" data-bind="value: ClientMatterDescription" readonly="readonly" />
                            <button type="button" class="btn btn-primary" data-bind="click: browseClientMatter">...</button>
                        </td>
                        <td>
                            <input type="text" class="form-control" data-bind="value: InvoiceNo" />
                        </td>
                        <td></td>
                    </tr>
                </tbody>
            </table>
        </div>

        <a href="#" data-bind="click: addInvoice">Add Row..</a>
        <br />
        <br />

        <div class="form-group">
            <div class="col-md-12">
                <input type="submit" value="Submit" class="btn btn-primary" />
            </div>
        </div>
    </div>
</form>

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<!-- Client Modal -->
@{ Html.RenderPartial("~/Views/Client/_Modal.cshtml"); }

<!-- SubsidiaryClient Modal -->
@{ Html.RenderPartial("~/Views/SubsidiaryClient/_Modal.cshtml"); }

<!-- LookupFirmMatter Modal -->
@{ Html.RenderPartial("~/Views/LookupFirmMatter/_Modal.cshtml"); }

<!-- ClientMatter Modal -->
@{ Html.RenderPartial("~/Views/ClientMatter/_Modal.cshtml"); }

@section Scripts {
    @Scripts.Render("~/bundles/knockout")
    <script>
        function Invoice() {
            var self = this;

            self.SubsidiaryClientID = ko.observable();
            self.SubsidiaryClientNo = ko.observable();
            self.SubsidiaryClientName = ko.observable();
            self.FirmMatterNo = ko.observable();
            self.FirmMatterDescription = ko.observable();
            self.FirmMatterLocation = ko.observable();
            self.LocationDescription = ko.observable();
            self.ClientMatterID = ko.observable();
            self.ClientMatterNo = ko.observable();
            self.ClientMatterDescription = ko.observable();
            self.InvoiceNo = ko.observable();

            self.browseSubsidiaryClient = function () {
                if ($("#ClientID").val() == "0") {
                    alert("Please select client");
                    $("#btnLookupClient").focus();
                    return false;
                }
                $.ajax({
                    type: "GET",
                    url: '@Url.Content("~/SubsidiaryClient/Lookup?officeID=")' + $("#OfficeID").val() + '&clientID=' + $("#ClientID").val(),
                    cache: false
                }).done(function (data) {
                    if (!data.message) {
                        $("#lookup-subsidiaryclient-container").html(data);
                        $("#subsidiaryClientModal").modal({ show: true, backdrop: true });
                    } else {
                        $("#subsidiaryClientModal").modal("hide");
                        alert(data.message);
                    }
                });
            };
            self.browseFirmMatter = function () {

            };
            self.browseClientMatter = function () {

            };
        }
        function InvoiceCreateViewModel() {
            var self = this;

            // Non-editable data
            self.Offices = ko.observableArray();

            // Editable data
            self.OfficeID = ko.observable();
            self.ClientID = ko.observable(0);
            self.Invoices = ko.observableArray([]);

            // Operations
            self.browseClient = function () {
                $.ajax({
                    type: "GET",
                    url: '@Url.Content("~/Client/LookupHasEBilling?c_officeID=")' + $("#OfficeID").val(),
                    cache: false
                }).done(function (data) {
                    if (!data.message) {
                        $("#lookup-client-container").html(data);
                        $("#clientModal").modal({ show: true, backdrop: true });
                    } else {
                        $("#clientModal").modal("hide");
                        alert(data.message);
                    }
                });
            }
            self.addInvoice = function () {
                self.Invoices.push(new Invoice());
            };
            self.removeInvoice = function (invoice) {
                self.Invoices.remove(invoice);
            }
        }

        $(document).ready(function () {
            var invoiceCreateViewModel = new InvoiceCreateViewModel();

            $.getJSON("@Url.Content("~/Office/GetOffices")", null, function (data) {
                invoiceCreateViewModel.Offices(data);
            });

            ko.applyBindings(invoiceCreateViewModel);

            $("#subsidiaryClientModal").on("click", "#btnSubmitSubsidiaryClient", function (e) {
                e.preventDefault();
                $.ajax({
                    type: "POST",
                    url: "@Url.Content("~/SubsidiaryClient/Lookup")",
                    data: {
                        officeID: $("#OfficeID").val(),
                        clientID: $("#ClientID").val(),
                        filterField: $("#SubsidiaryClientFilterField").val(),
                        filterOperator: $("#SubsidiaryClientFilterOperator").val(),
                        filterValue: $("#SubsidiaryClientFilterValue").val()
                    },
                    cache: false
                }).done(function (data) {
                    $("#lookup-subsidiaryclient-container").html(data);
                });
            });
        });

        function setClient(clientID, name) {
            document.getElementById("ClientID").value = clientID;
            document.getElementById("ClientName").value = name;

            $("#clientModal").modal("hide");
        }

        function setSubsidiaryClient(subsidiaryClientID, subsidiaryClientNo, name) {
            document.getElementById("SubsidiaryClientID").value = subsidiaryClientID;
            document.getElementById("SubsidiaryClientNo").value = subsidiaryClientNo;
            document.getElementById("SubsidiaryClientName").value = name;
            $("#subsidiaryClientModal").modal("hide");
        }
    </script>
}

查看:_Modal.cshtml(SubsidiaryClient&#39;模式)

<div class="modal fade" id="subsidiaryClientModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                <h4 class="modal-title" id="myModalLabel">Lookup Subsidiary Client</h4>
                @using (Html.BeginForm())
                {

                    <div class="form-inline">
                        <div class="form-group">
                            @Html.DropDownList("SubsidiaryClientFilterField",
                            new List<SelectListItem>
                            {
                                new SelectListItem { Text = "Subsidiary Client No", Value = "SubsidiaryClientNo" },
                                new SelectListItem { Text = "Name", Value = "Name" }
                            },
                            new { @class = "form-control" })
                        </div>
                        <div class="form-group">
                            @Html.DropDownList("SubsidiaryClientFilterOperator",
                            new List<SelectListItem>
                            {
                                new SelectListItem { Text = "Contains", Value = "Contains" },
                                new SelectListItem { Text = "Does Not Contain", Value = "Does Not Contain" },
                                new SelectListItem { Text = "=", Value = "=" },
                                new SelectListItem { Text = "<>", Value = "<>" },
                                new SelectListItem { Text = ">", Value = ">" },
                                new SelectListItem { Text = "<", Value = "<" },
                                new SelectListItem { Text = ">=", Value = ">=" },
                                new SelectListItem { Text = "<=", Value = "<=" }
                            },
                            new { @class = "form-control" })
                        </div>
                        <div class="form-group">
                            @Html.TextBox("SubsidiaryClientFilterValue", null, new { @class = "form-control", @placeholder = "Enter keyword" })
                        </div>
                        <input type="submit" id="btnSubmitSubsidiaryClient" value="Search" class="btn btn-primary" />
                    </div>
                }
            </div>
            <div class="modal-body" id="lookup-subsidiaryclient-container">
            </div>
        </div>
    </div>
</div>

控制器:

public ActionResult Lookup(short officeID, int clientID, string filterField, string filterOperator, string filterValue, int? page)
{
    var subsidiaryClients = db.SubsidiaryClients.Where(sc => sc.OfficeID == officeID && sc.ClientID == clientID);

    if (!string.IsNullOrEmpty(filterValue))
    {
        if ("Contains".Equals(filterOperator))
        {
            subsidiaryClients = subsidiaryClients.Where(filterField + ".Contains(@0)", filterValue);
        }
        else if ("Does Not Contain".Equals(filterOperator))
        {
            subsidiaryClients = subsidiaryClients.Where("!" + filterField + ".Contains(@0)", filterValue);
        }
        else
        {
            subsidiaryClients = subsidiaryClients.Where(filterField + " " + filterOperator + " @0", filterValue);
        }
    }

    subsidiaryClients = subsidiaryClients.OrderBy(sc => sc.Name);

    ViewBag.officeID = officeID;
    ViewBag.clientID = clientID;
    ViewBag.filterField = filterField;
    ViewBag.filterOperator = filterOperator;
    ViewBag.filterValue = filterValue;

    var pagedSubsidiaryClients = subsidiaryClients.ToPagedList(page ?? 1, Global.RowsPerPage);
    var subsidiaryClientsVM = Mapper.Map<IEnumerable<SubsidiaryClient>, IEnumerable<SubsidiaryClientViewModel>>(pagedSubsidiaryClients.ToArray());
    var pagedSubsidiaryClientsVM = new StaticPagedList<SubsidiaryClientViewModel>(subsidiaryClientsVM, pagedSubsidiaryClients.GetMetaData());

    return PartialView("_Lookup", pagedSubsidiaryClientsVM);
}

部分视图显示SubsidiaryClient的数据:

<table class="table table-striped table-hover table-condensed">
    <tr>
        <th></th>
        <th>Subsidiary Client No</th>
        <th>Name</th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td><a href="javascript:setSubsidiaryClient('@item.SubsidiaryClientID', '@item.SubsidiaryClientNo', '@item.Name.Replace("'", "\\'")')" class="glyphicon glyphicon-ok-sign"></a></td>
            <td>@Html.DisplayFor(modelItem => item.SubsidiaryClientNo)</td>
            <td>@Html.DisplayFor(modelItem => item.Name)</td>
        </tr>
    }
</table>

2 个答案:

答案 0 :(得分:1)

抱歉Willy,我已经在asp .net上工作了,所以我只提供了一个敲门和html的示例代码。希望这可以帮助你

<强> HTML

// Parent Page Code
<!-- ko foreach: ClientList -->
<!-- ko if: isActive -->
<div class="col-xs-12">
    <div class="col-xs-4" data-bind="text: SubsidiaryClientID"></div>
    <div class="col-xs-4" data-bind="text: SubsidiaryClientNo"></div>
    <div class="col-xs-4" data-bind="text: SubsidiaryClientName"></div>
</div>
<!-- ko -->
<!-- /ko -->

// Modal Box List
<!-- ko foreach: ClientList -->
<div class="col-xs-12" data-bind="click: $parent.Add">
    <div class="col-xs-4" data-bind="text: SubsidiaryClientID"></div>
    <div class="col-xs-4" data-bind="text: SubsidiaryClientNo"></div>
    <div class="col-xs-4" data-bind="text: SubsidiaryClientName"></div>
</div>
<!-- /ko -->

<强>敲除

// Child view-model for Client List

SubsidiaryClientVM = function(){

    this.SubsidiaryClientID = ko.observable();
    this.SubsidiaryClientNo = ko.observable();
    this.SubsidiaryClientName = ko.observable();
    this.isActive = ko.observable(false);

}

// Parent view model
vm = function(){
    var self = this;
    this.ClientList = ko.observableArray();

    // fill the array on search etc...
    this.onSearch = function(){
        self.ClientList(jQuery.map(data.Clients, function (item) {
            return new SubsidiaryClientVM(item);
        }));
    }

    this.Add = function(item){
        ko.utils.arrayForEach(self.ClientList, function(list){
            if(list.SubsidiaryClientID == item.SubsidiaryClientID){
                list.isActive(!list.isActive());
            }
        });
    }
}

答案 1 :(得分:0)

您可以在每一行定义自己的属性,并将该ro分配给js函数。

像这样:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cs1="https://defaultnamespace/abc" xmlns:cs2="https://defaultnamespace1/abc" exclude-result-prefixes="cs1 cs2">
  <xsl:template match="/">
      <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="cs1:Report">
    <xsl:for-each select="cs1:Conversion/cs1:Type">
      <xsl:element name="Converting">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>
    <xsl:element name="LastOne">
      <xsl:value-of select="cs1:Last"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="cs2:Report">
    <xsl:for-each select="cs2:Conversion/cs2:Type">
      <xsl:element name="Converting">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>
    <xsl:element name="LastOne">
      <xsl:value-of select="cs2:Last"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>