【问题标题】:KnockoutJS - Observable Array of Observable objectsKnockoutJS - 可观察对象的可观察数组
【发布时间】:2012-04-20 08:53:48
【问题描述】:

我想显示一个可编辑的项目列表,其中的每个项目都是可编辑的(在某种程度上,有点像可编辑的网格)。我正在使用 KnockoutJS。我不能只使用一个简单的 Observable Array,因为正如文档所述“一个 observableArray 跟踪数组中的哪些对象,而不是这些对象的状态”

所以,我创建了一个可观察对象的 observableArray(使用 utils.arrayMap),并将它们绑定到视图。但是,问题是,如果我在屏幕上编辑数据,用户在屏幕上所做的任何数据输入更改似乎都不会生效。见http://jsfiddle.net/AndyThomas/E7xPM/

我做错了什么?

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

});

【问题讨论】:

    标签: knockout.js observable ko.observablearray


    【解决方案1】:

    ko.utils.arrayMap 不会将视图模型的属性映射为可观察对象,这就是为什么您看不到它们动态更新的原因。

    如果您将 CategoryId 定义为 observable,您会看到它按预期更新:

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

    查看更新后的 jsfiddle:http://jsfiddle.net/tuando/E7xPM/5/

    【讨论】:

      【解决方案2】:

      为了跟进 Tuan 的回答,我需要根据从 ASP.Net MVC 控制器的服务器方法返回的数据填充我的对象,其中产品列表包含在视图的模型中,类别列表用于下拉框位于 ViewBag 中。我使用了以下代码(另见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);
      
      });
      

      谢谢团!

      【讨论】:

      【解决方案3】:

      我正在使用在调用 ko.utils.arrayMap 时初始化的可写计算 observables

      在您的情况下可能有点矫枉过正,但它可能会帮助其他人。看到这个 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);
        });
      

      【讨论】:

        猜你喜欢
        • 2017-11-25
        • 1970-01-01
        • 2019-09-09
        • 1970-01-01
        • 2015-09-18
        • 2015-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多