使用Knockoutjs的绑定日期

Wil*_*lly 6 javascript knockout.js momentjs

使用knockout将日期值绑定到文本框时出现问题,如下图所示 在此输入图像描述

当第一次加载页面时,我使用ajax来获取AccountStatements数据.

function AccountStatementViewModel(companyID) {
    var self = this;
    ...
    var AccountStatement = {
        AccountStatementID: self.AccountStatementID,
        CompanyID: self.CompanyID,
        Description: self.Description,
        Amount: self.Amount,
        ReceiptDate: self.ReceiptDate,
        Type: self.Type
    }

    self.AccountStatement = ko.observable();
    self.AccountStatements = ko.observableArray();

    $.ajax({
        url: webroot + 'AccountStatement/GetAccountStatements',
        contentType: 'application/json; charset=utf-8',
        data: { id: self.CompanyID },
        cache: false
    }).done(function (data) {
        self.AccountStatements(data);
    });
    ...
    self.edit = function (accountStatement) {
        $('#lnkAddAccountStatement').hide('blind', 1000);
        $('#pnlAddEditAccountStatement').show('blind', 1000);
        self.AccountStatement(accountStatement);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

Controller在json中返回结果:

public JsonResult GetAccountStatements(int id)
{
    var accountStatementsVM = db.AccountStatements
        .Where(a => a.CompanyID == id)
        .Select(a => new AccountStatementViewModel
        {
            AccountStatementID = a.AccountStatementID,
            CompanyID = a.CompanyID,
            Description = a.Description,
            Amount = a.Amount,
            ReceiptDate = a.ReceiptDate,
            Type = a.Type
        })
        .ToList();

    return Json(accountStatementsVM, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)

蚂蚁的结果是:

[{"AccountStatementID":2,"CompanyID":1,"Description":"test","Amount":1000,"ReceiptDate":"/Date(1447261200000)/","Type":"Payment"}]
Run Code Online (Sandbox Code Playgroud)

在视图中,我使用以下代码显示它:

<tbody data-bind="foreach: AccountStatements, visible: AccountStatements().length > 0">
    <tr>
        <td data-bind="attr: { id: AccountStatementID }">
            <a href="#" class="btn btn-primary btn-xs" data-bind="click: $root.edit"><i class="glyphicon glyphicon-pencil"></i></a>
            <a href="#" class="btn btn-danger btn-xs" data-bind="click: $root.delete"><i class="glyphicon glyphicon-remove"></i></a>
        </td>
        <td data-bind="text: Description"></td>
        <td data-bind="text: Amount"></td>
        <td data-bind="date: ReceiptDate"></td>
    </tr>
</tbody>
Run Code Online (Sandbox Code Playgroud)

以下是格式化日期的代码:

ko.bindingHandlers.date = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
        var textContent = moment(valueUnwrapped).format("DD/MM/YYYY");
        ko.bindingHandlers.text.update(element, function () { return textContent; });
    }
};
Run Code Online (Sandbox Code Playgroud)

在此步骤中,日期以正确的格式显示,如果单击编辑按钮,则文本框中的ReceiptDate不会格式化.

ReceiptDate TextBox的代码:

<input type="text" placeholder="Enter Receipt Date" class="form-control fdatepicker" readonly="readonly" data-bind="value: AccountStatement().ReceiptDate" />
Run Code Online (Sandbox Code Playgroud)

如果我更改为data-bind="date: AccountStatement().ReceiptDate"文本框将为空.

如何格式化文本框中的日期?

UPDATE

我已经更改了此链接中的日期绑定处理程序,但ReceiptDate的TextBox值仍然是/Date(1447261200000)/

视图中的更改:

<input type="text" placeholder="Enter Receipt Date" class="form-control fdatepicker" readonly="readonly" data-bind="date: AccountStatement().ReceiptDate" />
Run Code Online (Sandbox Code Playgroud)

表格中的收据日期为空:

<td data-bind="date: ReceiptDate"></td>
Run Code Online (Sandbox Code Playgroud)

Roy*_*y J 0

在您的更新中,$root.ReceiptDate不存在。ReceiptDate是 AccountStatement 数据的成员。跟踪上下文的级别很重要。

您的date绑定将设置 a value,因此您不能将其用于需要text绑定的内容(例如td更新示例中的 a )。

为此,您不需要绑定,您只需要一个格式化函数,您可以在您选择的任何绑定中使用它。如果您希望能够编辑该值,那么您应该根据日期值进行可写计算value并在绑定中使用它。我在这里不演示这一点。

ajaxData = [{
  "AccountStatementID": 2,
  "CompanyID": 1,
  "Description": "test",
  "Amount": 1000,
  "ReceiptDate": "/Date(1447261200000)/",
  "Type": "Payment"
}];


vm = {
  AccountStatements: ko.observableArray(ajaxData),
  formatDate: function(textValue) {
    return moment(textValue).format("DD/MM/YYYY");
  }
};

ko.applyBindings(vm);

// Add a row
setTimeout(function() {
  vm.AccountStatements.push({
    "AccountStatementID": 2,
    "CompanyID": 1,
    "Description": "test",
    "Amount": 1000,
    "ReceiptDate": "/Date(1448271200000)/",
    "Type": "Payment"
  })
}, 2500);
Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<table border=1>
  <tbody data-bind="foreach: AccountStatements, visible: AccountStatements().length > 0">
    <tr>
      <td data-bind="attr: { id: AccountStatementID }"> <a href="#" class="btn btn-primary btn-xs" data-bind="click: $root.edit"><i class="glyphicon glyphicon-pencil"></i></a>
        <a href="#" class="btn btn-danger btn-xs" data-bind="click: $root.delete"><i class="glyphicon glyphicon-remove"></i></a>

      </td>
      <td data-bind="text: Description"></td>
      <td data-bind="text: Amount"></td>
      <td data-bind="text: $parent.formatDate(ReceiptDate)"></td>
      <td>
        <input type="text" class="form-control fdatepicker" readonly="readonly" data-bind="value: $parent.formatDate(ReceiptDate)" />
      </td>
    </tr>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)