2017-04-25 62 views
0

我有很多(KnockOut)视图模型从一个rest服务获取数据,然后填充非常简单的“item”视图模型,只包含来自REST接口的字段。Dynamic Item ViewModel Knockout

我只是想知道是否有一种方法不必定义项目viewmodels,但不知何故只是创建它们动态作为对象(其中每个属性是可观察的)。

所以在下面的例子中,我想不要有“ItemViewModel”,但只需在AddItems函数中说它应该基于数据创建一个对象并使每个条目成为ko.observable。传递的“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

没有如果。你的对象很简单,没有牛逼嵌套,您可以编写代码来自己把它们映射:

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>

我想通过这个天真的实现阅读是很重要的:它会让你明白为什么它可能是一个更好的主意,用一个现成的插件

只要您的服务器端代码包含数组,嵌套视图模型或您不想映射的任何属性,就会遇到问题。 ko.mapping插件已经为您解决了这些问题。它将阵列映射到ko.observableArray s,并让您指定映射策略。

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>

相关问题