30

編集可能なアイテムのリストを表示したいと思います。各アイテムは編集可能です(ある意味、編集可能なグリッドのようなものです)。KnockoutJSを使用しています。ドキュメントに「observableArrayは、それらのオブジェクトの状態ではなく、配列内のオブジェクトを追跡する」と記載されているため、単純なObservableArrayだけを使用することはできません。

そこで、(utils.arrayMapを使用して)監視可能なオブジェクトのobservableArrayを作成し、それらをビューにバインドしました。ただし、問題は、画面上のデータを編集すると、ユーザーが画面上で行ったデータ入力の変更が有効に表示されないことです。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);

});

</ p>

4

3 に答える 3

20

ko.utils.arrayMapは、ビューモデルのプロパティをオブザーバブルとしてマップしないため、動的に更新されていないことがわかります。

CategoryIdを監視可能として定義すると、期待どおりに更新されます。

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

この更新されたjsfiddleを参照してください:http://jsfiddle.net/tuando/E7xPM/5/

于 2012-04-06T20:16:37.793 に答える
17

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

});

ありがとう、トゥアン!

于 2012-04-07T15:39:03.600 に答える
1

ko.utils.arrayMapの呼び出しで初期化される書き込み可能な計算されたオブザーバブルを使用しています

あなたの場合はやり過ぎかもしれませんが、それは他の誰かを助けるかもしれません。この jsFiddleサンプルを参照してください

  // 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);
  });
于 2013-05-10T20:17:45.760 に答える