2017-04-25 20 views
0

私は、休憩サービスからデータを取得し、かなりシンプルで、RESTインターフェイスからのフィールドを含む「アイテム」ビューモデルにデータを取り込む多くの(KnockOut)ビューモデルを持っています。ダイナミックアイテムViewModelノックアウト

アイテムのviewmodelsを定義何とかだけ(各プロパティが観察される)オブジェクトとして動的にそれらを作成する必要がないようにする方法があった場合、私はちょうど思っていました。

以下の例では、 "ItemViewModel"を持たずに、データに基づいてオブジェクトを作成して各エントリをko.observableにする必要があることをAddItems関数内で言います。渡された "itemName"には "ItemViewModel1"(または他の "ItemViewModel2"など)が含まれます。

JSONレスト入力フィールド「LAST_NAME」を持っている場合、それは(私はまだビューでそれを参照することができます)self.LAST_NAME = ko.observable()」など、その値で埋めを追加します。

var ItemViewModel1 = function (data) { 
    var self = this; 
    self.PAR1 = ko.observable(data.PAR1) 
    self.PAR2 = ko.observable(data.PAR2) 
    self.PAR3 = ko.observable(data.PAR3) 
    self.PAR4 = ko.observable(data.PAR4) 
    // … etc 
} 
var MasterViewModel1 = function (data) { 
    var self = this; 
    ReportBaseViewModel.call(self) 
} 

var ReportBaseViewModel = function() { 
    var self = this; 

    /* commonly used vars */ 
    self.report = ko.observable(); 
    self.searchedCallBackFunction = ko.observable(); 
    self.items = ko.observableArray(); 
    self.selecteditem = ko.observable(); 
    self.selectedPerson = ko.observable(); 

    /* method: print */ 
    self.PrintEventHandler = function (data) { window.print(); }; 

    /* method: add items to array */ 
    self.AddItems = function (data) { 
     var newitems = ko.utils.arrayMap(data, function (item) { 
      c = new window[self.itemname](item); 
      return c; 
     }); 
     self.items(newitems); 
    }; 

    /* eventhandler: select one item */ 
    self.SelectEventHandler = function (item) { 
     selecteditem(item); 
    }; 

    self.GetReport = function (selectedPerson, viewContainer, url, itemName) { 
     self.selectedPerson(selectedPerson); 
     self.itemname = itemName; 
     var jqxhr = $.ajax({ 
      url: url, 
      type: "GET" 
     }).done(function (data, textStatus, jqXHR) { 
      if (data != null) { 
       self.AddItems(data); 
       $('#' + viewContainer).show(); 
       document.getElementById(viewContainer).scrollIntoView(); 
      } 
     }).fail(function (jqXHR, textStatus, errorThrown) { 
      console.log('fail' + JSON.stringify(jqXHR)); 
      toastr.options = { 
       "closeButton": true, 
       "debug": false, 
       "newestOnTop": false, 
       "progressBar": false, 
       "positionClass": "toast-top-right", 
       "preventDuplicates": false, 
       "onclick": null, 
       "showDuration": "0", 
       "hideDuration": "1000", 
       "timeOut": "0", 
       "extendedTimeOut": "0", 
       "showEasing": "swing", 
       "hideEasing": "linear", 
       "showMethod": "fadeIn", 
       "hideMethod": "fadeOut" 
      }; 
      toastr["error"]("ERROR"); 
     }).always(function (jqXHR, textStatus, errorString) { 
      if (typeof self.searchedCallBackFunction() === 'function') { 
       self.searchedCallBackFunction(); 
      } 
     }); 
    } 
} 

答えて

1

がある場合あなたのオブジェクトはシンプルでありません。ネストされた、あなたがそれらを自分でマッピングするためにコードを書くことができますT:

var someJSON = '{ "firstName": "John", "lastName": "Doe" }'; 
 

 
var makeSimpleVM = function(obj) { 
 
    // Return a new object with all property 
 
    // values wrapped in an observable 
 
    return Object 
 
    .keys(obj) 
 
    .reduce(function(vm, key) { 
 
     vm[key] = ko.observable(obj[key]); 
 
     return vm; 
 
    }, {}); 
 
}; 
 

 
var myVM = makeSimpleVM(JSON.parse(someJSON)); 
 

 
console.log(ko.isObservable(myVM.firstName)); // true 
 
console.log(myVM.firstName()); // John 
 

 
myVM.firstName("Jane"); 
 
console.log(myVM.firstName()); // Jane
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

私はそれがこの素朴な実装を通読することが重要だと思う:それは使用するために、おそらくより良いアイデアだ理由あなたが理解してます既製のプラグイン

はできるだけ早く、サーバー側のコードは、配列、入れ子になったのviewmodelsまたはあなたがマッピングされたくないプロパティが含まれているとして、あなたは問題に実行されます。 ko.mappingプラグインは、すでにこれらの問題を解決しています。配列をko.observableArrayにマップし、マッピング方法を指定できるようにします。

var someJSON = '{ "firstName": "John", "lastName": "Doe" }'; 
 

 
// Let's use the library this time 
 
var myVM = ko.mapping.fromJS(JSON.parse(someJSON)); 
 

 
console.log(ko.isObservable(myVM.firstName)); // true 
 
console.log(myVM.firstName()); // John 
 

 
myVM.firstName("Jane"); 
 
console.log(myVM.firstName()); // Jane
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>

関連する問題