2015-11-13 12 views
6

Tôi đã có một vấn đề khi ràng buộc giá trị ngày tháng để textbox sử dụng loại trực tiếp, như đã thấy trong hình dưới đây enter image description hereBinding ngày sử dụng Knockoutjs

Khi trang web được tải lần đầu tiên, tôi đang sử dụng ajax để nhận được dữ liệu 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); 
    } 
    ... 
} 

Controller trả về kết quả trong 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); 
} 

kiến ​​kết quả là:

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

Trong View, tôi hiển thị nó sử dụng mã này:

<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> 

Đây là mã để định dạng ngày:

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; }); 
    } 
}; 

Ở bước này, ngày được hiển thị ở đúng định dạng, sau đó nếu tôi nhấp vào nút chỉnh sửa, biên nhận trong hộp văn bản không được định dạng.

Mã cho ReceiptDate TextBox:

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

Nếu tôi thay đổi để data-bind="date: AccountStatement().ReceiptDate" hộp văn bản sẽ được bỏ trống.

Cách định dạng ngày trong hộp văn bản?

CẬP NHẬT

Tôi đã thay đổi xử lý ràng buộc ngày như trong link này nhưng giá trị TextBox của ReceiptDate vẫn là /Date(1447261200000)/

Những thay đổi trong giao diện:

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

và ngày biên nhận trong bảng bị trống:

<td data-bind="date: ReceiptDate"></td> 
+0

một cái gì đó như thế này http://jsfiddle.net/LkqTU/27696 /. chúc mừng –

+0

@supercool cảm ơn vì liên kết nhưng nó không hoạt động. Trong liên kết ở trên, bạn đã sử dụng định dạng ngày chung (dd/mm/yyyy), trong khi trong trường hợp của tôi, giá trị ngày ở định dạng ngày tháng json '/ Date (1447261200000) /'. Tôi đã chỉnh sửa câu hỏi của mình để cung cấp thêm thông tin. – Willy

+0

thử đặt 'self.ReceiptDate = ko.observable (1447261200000);' và kiểm tra nó, nó vẫn hoạt động. thời điểm sẽ giải mã thành ngày và định dạng u được chỉ định. –

Trả lời

0

Trong bản cập nhật của bạn, $root.ReceiptDate không tồn tại. ReceiptDate là thành viên của dữ liệu AccountStatement. Điều quan trọng là phải theo dõi các mức ngữ cảnh.

bạn date ràng buộc sẽ thiết lập một value, vì vậy bạn không thể sử dụng nó cho một cái gì đó sẽ mất một text ràng buộc (như một td trong ví dụ cập nhật của bạn).

Bạn không cần một ràng buộc cho điều này, bạn chỉ cần một chức năng định dạng, mà bạn có thể sử dụng trong bất kỳ ràng buộc bạn chọn. Nếu bạn muốn có thể chỉnh sửa giá trị, thì bạn nên tạo một writable computed dựa trên giá trị ngày của bạn và sử dụng giá trị đó trong một ràng buộc value. Tôi không chứng minh điều đó ở đây.

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);
<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>

+0

Tôi đã cố sử dụng tính toán có thể ghi, nhưng vẫn không hoạt động. Vấn đề là khi bạn nhấp vào nút chỉnh sửa ngày (trong hộp văn bản) không được định dạng và ngày tháng lịch biểu không xuất hiện. http://jsfiddle.net/qdh9jw94/5/ – Willy

+0

Bạn có đầu vào được đánh dấu là 'readonly', cho một. Datepicker của bạn có thể cần một trình xử lý ràng buộc tùy chỉnh. http://stackoverflow.com/questions/13629910/jquery-ui-datepicker-with-knockout-js Bạn có thể cần phải đặt một câu hỏi mới. –

+0

@Willy Chức năng chỉnh sửa của bạn nhận dữ liệu 'accountStatement' từ' dữ liệu' chưa được mở mà bạn đã gán cho 'AccountStatements'. –

1

Làm một đấu thầu tùy chỉnh là một overkill.Ràng buộc tùy chỉnh của bạn không làm bất cứ điều gì xứng đáng với một ràng buộc tùy chỉnh.

Tất cả những gì bạn cần là một quan sát được tính toán trả về định dạng văn bản của ngày hiện tại.

Hãy nói rằng bạn có biến này ở đâu đó:

var myDate = ko.observable(); 

Và ở đâu đó bạn có mã mà đặt một số đối tượng ngày trong đó:

myDate(input); // where input is some date object you got somehow from somewhere 

Bây giờ tất cả bạn cần là thế này:

myDate.formatted = ko.pureComputed(function() { 
    return moment(myDate()).format("DD/MM/YYYY"); 
}); 

Bây giờ bạn chỉ có thể sử dụng liên kết văn bản thông thường:

(giả sử bạn có myDate trong mô hình điểm ràng buộc để quan điểm này)

<td data-bind="text: myDate.formatted"></td> 

LƯU Ý:

Không có gì đặc biệt về myDate.formatted là. Nếu bạn nghĩ về nó, myDate chỉ là một hàm và các hàm là các đối tượng để bạn có thể đính kèm các trường tùy ý vào chúng.

Nó thực sự không có khác nhau ở tất cả các từ tạo ra một biến mới như thế này:

var myFormattedDate = ko.pureComputed(function() { 
    return moment(myDate()).format("DD/MM/YYYY"); 
}); 

Và sử dụng nó trong một ràng buộc:

<td data-bind="text: myFormattedDate"></td> 
+0

Điều này thậm chí còn dễ dàng hơn khi được trừu tượng hóa thành một trình mở rộng: 'ko.extenders.formattedDate = function() {...}' và sau đó được sử dụng như 'myDate.extend ({formattedDate:" DD/MM/YYYY "})'. Lợi thế rõ ràng là khả năng sử dụng lại, ràng buộc có thể giữ nguyên. – Tomalak

+0

Nó không hoạt động, ngày trong bảng không xuất hiện, đây là liên kết http://jsfiddle.net/qdh9jw94/6/. Trên thực tế, vấn đề là làm thế nào để ràng buộc ngày vào hộp văn bản ReceiptDate khi ở chế độ chỉnh sửa (bằng cách nhấn vào nút chỉnh sửa) – Willy

Các vấn đề liên quan