通过敲除绑定获取所有填充的输入

时间:2016-11-04 10:14:35

标签: javascript typescript knockout.js

我有一些带有一些可观察属性的viewModel。此viewModel绑定到searchForm。我只需要用填充的输入创建请求,换句话说,我需要获取所有属性,其中有一些值。

如何才能获得有价值的所有字段?

class AdvancedSearchModel {
    clientKey: any = ko.observable('');
    uid: any = ko.observable('');
    name: any = ko.observable('');

    address1: any = ko.observable('');
    address2: any = ko.observable('');
    city: any = ko.observable('');
    province: any = ko.observable('');
    state: any = ko.observable('');
    country: any = ko.observable('');
    postalCode: any = ko.observable('');

    phone: any = ko.observable('');
    fax: any = ko.observable('');

    longitude: any = ko.observable('');
    latitude: any = ko.observable('');
}

目前我只看到一个解决方案,如果它有价值,则单独检查每个字段。

if(this.clientKey() != ''){ //...}

另一种可能更短的方式(根据@ user3297291回答):

let whereObject: any = {};
Object.keys(locationModel).forEach(property => {
    if (!whereObject.hasOwnProperty(property) && locationModel[property]() != '') {
         whereObject[property] = { "eq": locationModel[property]() };
    }
});

但我仍然遍历每个领域。

1 个答案:

答案 0 :(得分:0)

您需要以某种方式创建相关字段的集合。使用该集合,您将能够创建一个计算对象,在没有输入的情况下过滤掉字段。

制作此类收藏品的三种方法:

  • 使用Object.keys(viewModel):这将返回viewmodel的每个属性。您必须将viewmodel的属性限制为您在数据中所需的属性。
  • 创建表单字段名称的单独数组,例如:[this.clientKey, this.uid, /* etc. */]
  • 创建一个对象,其中包含您希望字段在最终数据中具有的键名以及对viewmodel属性的引用

示例:明确定义要包含的属性

以下是最后一个选项如何运作的示例:

  • formFields包含我们想要包含的属性。
  • filledIn订阅所有这些字段中的更改
  • reduce过滤掉没有值的属性



var ViewModel = function() {
  this.a = ko.observable("");
  this.b = ko.observable("");
  this.c = ko.observable("");

  var formFields = {
    "a": this.a,
    "b": this.b,
    "c": this.c
  };
  
  this.filledIn = ko.pureComputed(function() {
    var val;
    return JSON.stringify(Object.keys(formFields) // An array of all keys
      .reduce(function(result, key) {             // Create an object
        val = ko.unwrap(formFields[key]);         // See if there's a value
        if (val) result[key] = val;               // Add to new object if there is
        return result;
      }, {}), null, 2);                           // Stringify settings for UI
  }, this);
  
};

ko.applyBindings(new ViewModel());

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<input data-bind="textInput: a, attr: {placeholder: 'a'}">
<input data-bind="textInput: b, attr: {placeholder: 'b'}">
<input data-bind="textInput: c, attr: {placeholder: 'c'}">

<pre data-bind="text: filledIn"></pre>
&#13;
&#13;
&#13;

示例:包括 viewmodel的所有属性

如果你不喜欢&#34;复制&#34;在formFields内,你可以重构这样的事情:

&#13;
&#13;
var FormViewModel = function() {
  this.a = ko.observable("");
  this.b = ko.observable("");
  this.c = ko.observable("");
};

var ViewModel = function() {
  var self = this;
  
  this.form = new FormViewModel();
  
  this.filledIn = ko.pureComputed(function() {
    var val;
    return JSON.stringify(Object.keys(self.form)
      .reduce(function(result, key) {
        val = ko.unwrap(self.form[key]);
        if (val) result[key] = val;
        return result;
      }, {}), null, 2);
  });
  
};

ko.applyBindings(new ViewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div data-bind="with: form">
  <input data-bind="textInput: a, attr: {placeholder: 'a'}">
  <input data-bind="textInput: b, attr: {placeholder: 'b'}">
  <input data-bind="textInput: c, attr: {placeholder: 'c'}">
</div>
<pre data-bind="text: filledIn"></pre>
&#13;
&#13;
&#13;