2012-04-06 35 views
28

Tôi muốn hiển thị danh sách các mục có thể chỉnh sửa, mỗi mục có thể chỉnh sửa được (loại giống như lưới có thể chỉnh sửa, theo cách này). Tôi đang sử dụng KnockoutJS. Tôi không thể sử dụng một mảng quan sát đơn giản bởi vì, tài liệu chỉ ra "Một đường quan sát được các đối tượng nằm trong mảng, không phải trạng thái của các đối tượng"KnockoutJS - Dải quan sát của các đối tượng quan sát

Vì vậy, tôi đã tạo một đối tượng quan sát được (sử dụng utils). arrayMap) và ràng buộc chúng vào khung nhìn. Tuy nhiên, vấn đề là nếu tôi chỉnh sửa dữ liệu trên màn hình, mọi thay đổi nhập dữ liệu mà người dùng thực hiện trên màn hình sẽ không có hiệu lực. Xem http://jsfiddle.net/AndyThomas/E7xPM/

Tôi đang làm gì sai?

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js" type="text/javascript"></script> 

<table> 
    <tbody data-bind="template: { name:'productListJavascriptTemplate', foreach: products}"> 
    </tbody> 
</table> 


<script type="text/html" id="productListJavascriptTemplate"> 
<tr> 
    <td>Name: <input data-bind="value: Name"/></td> 
    <td>Name: <span data-bind="text: Name"/></td> 
    <td><select data-bind="options: this.viewModel.categories, 
     optionsText: 'Name', optionsValue: 'Id', value: CategoryId, 
     optionsCaption: 'Please select...'"></select></td> 
    <td>CategoryId: <input data-bind="value: CategoryId"/></td> 

</tr> 

</script>​ 

var categoryList= [ 
{ 
    Name: "Electronics", 
    Id: "1"}, 
{ 
    Name: "Groceries", 
    Id: "2"} 
]; 

var initialData= [ 
{ 
    Name: "Television", 
    CategoryId: "1"}, 
{ 
    Name: "Melon", 
    CategoryId: "2"} 
]; 

var viewModel = { 
    products: ko.observableArray(
     ko.utils.arrayMap(initialData, function(product) { 
           return ko.observable(product); 
     })), 
    categories: ko.observableArray(categoryList)  
}; 


$(function() { 
    ko.applyBindings(viewModel); 

}); 

Trả lời

18

ko.utils.arrayMap không lập bản đồ thuộc tính của viewmodel của bạn như quan sát, và đó là lý do tại sao bạn không nhìn thấy chúng được cập nhật tự động.

Nếu bạn xác định CategoryID của bạn như là một quan sát, bạn sẽ thấy nó cập nhật như mong đợi:

var initialData = [ 
    { 
     Name: "Television", 
     CategoryId: ko.observable("1") 
    }, 
    { 
     Name: "Melon", 
     CategoryId: ko.observable("2") 
    } 
]; 

Xem jsfiddle cập nhật này: http://jsfiddle.net/tuando/E7xPM/5/

+0

thanksssss hoàn hảo! – Andrew

14

Để theo dõi về câu trả lời của Tuấn, tôi cần phải cư đối tượng của tôi dựa trên dữ liệu được trả về từ phương thức máy chủ từ bộ điều khiển ASP.Net MVC, trong đó danh sách Sản phẩm được chứa trong Mô hình của khung nhìn và danh sách các loại cho hộp thả xuống nằm trong ViewBag. Tôi đã sử dụng mã sau (xem thêm http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html):

var initialData = @Html.Raw(new JavaScriptSerializer().Serialize(Model)); 
var categoryList = @Html.Raw(new JavaScriptSerializer().Serialize(ViewBag.CategoryList)); 

var ObservableProduct = function(name, description, categoryId) {   
    this.Name = ko.observable(name);   
    this.Description = ko.observable(description); 
    this.CategoryId = ko.observable(categoryId); 
}; 

var viewModel = { 
    products: ko.observableArray(ko.utils.arrayMap(initialData, function(product) { 
      return new ObservableProduct(product.Name, product.Description, product.CategoryId); 
     })), 
    categories: ko.observableArray(categoryList)  
}; 

$(function() { 
    ko.applyBindings(viewModel); 

}); 

Xin cảm ơn, Tuấn!

+0

Câu trả lời hay: có một số chi tiết ở đây http://lostechies.com/erichexter/2012/11/29/loading-knockout-view-models-from-asp-net-mvc/ –

1

Tôi đang sử dụng quan sát tính toán có thể ghi được khởi tạo trong các cuộc gọi đến ko.utils.arrayMap

Có thể là một overkill trong trường hợp của bạn, nhưng nó có thể giúp người khác. Xem phần này jsFiddle sample

// Writeable computed observables 
    function Customer(id, firstName, lastName, preferred) { 
    var self = this; 
    self.id = id; 
    self.firstName = firstName; 
    self.lastName = lastName; 
    // Non-Writeable computed observable 
    self.fullName = ko.computed(function() { 
     var fn = self.firstName; 
     var ln = self.lastName; 
     return ln ? fn + ' ' + ln : fn; 
    }, self); 
    self.preferred = ko.observable(preferred); 
    // Writeable computed observable 
    self.isPreferred = ko.computed({ 
     read: function() { 
      var preferredStr = self.preferred() || ''; 
      var isPreferredComputed = preferredStr.toUpperCase(); 
      return (isPreferredComputed === 'Y') ? true : false; 
     }, 
     write: function(value) { 
      self.preferred((!value) ? '' : (value ? 'Y' : ''));    
     }, 
     owner: self   
    });  
} 
    var mappedData = ko.utils.arrayMap(dataFromServer, function(customer) { 
     return new Customer(customer.id, customer.firstName, customer.lastName, customer.preferred); 
    }); 
Các vấn đề liên quan