2012-04-06 68 views
28

各アイテムが編集可能(編集可能なグリッドのようなもの)の編集可能なリストを表示したいと思います。私はKnockoutJSを使用しています。 "observableArrayは、どのオブジェクトが配列内にありオブジェクトの状態ではないかを追跡するため、単純なObservable Arrayは使用できません。"したがって、私はobservableオブジェクトのobservableArrayを作成しました(utilsを使用してobservableArrayを作成しました。 arrayMap)を作成し、ビューにバインドします。しかし、問題は、画面上のデータを編集すると、ユーザーが画面上で行うデータ入力の変更が有効にならないように見えるということです。 http://jsfiddle.net/AndyThomas/E7xPM/KnockoutJS - 観測可能なオブジェクトの観測可能配列

私は間違っていますか?

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

}); 

答えて

18

ko.utils.arrayMapは観測としてあなたのviewmodelのプロパティをマッピングしていない、とあなたがそれらを動的に更新表示されていない理由です。

あなたが観察できるよう、あなたの区分を定義する場合は、あなたが期待どおりに更新表示されます:

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

は、この更新jsfiddleを参照してください:トゥアンの答えをフォローアップするためにhttp://jsfiddle.net/tuando/E7xPM/5/

+0

完璧thanksssssを参照してください! – Andrew

14

を、私は移入するために必要な私のオブジェクトは、ビューのモデルにProductのリストが含まれ、ドロップダウンボックスのカテゴリのリストがViewBagにあるASP.Net MVCコントローラのサーバーメソッドから返されたデータに基づいています。私は(も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); 

}); 

おかげで、トゥアンを!私はko.utils.arrayMap

への呼び出しで初期化されている書き込み可能な計算された観測を使用しています

+0

ニースの回答:詳細はこちらhttp://lostechies.com/erichexter/2012/11/29/loading-knockout-view-models-from-asp-net-mvc/ –

1

は、あなたのケースではやり過ぎかもしれないが、それは他の誰かを助けるかもしれません。この 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); 
    }); 
関連する問題