2016-04-28 76 views
0

我想要构建一个HTML页面,允许用户构建一个对象,然后可以将该对象作为JSON发布到内部托管服务(类似于Chrome Advanced Rest Client )。用户必须能够添加和删除属性。挖掘或其他JavaScript来添加/删除对象的属性

我的模型不正确,因为每个属性都被视为具有属性'name'和'value'的对象。我最终得到了一个对象数组,而不是具有属性的对象。

下面是HTML的一个片段:

<table> 
     <thead> 
      <tr> 
       <th>Property Name</th> 
       <th>Property Value</th> 
       <th></th> 
      </tr>    
     </thead> 
     <tbody data-bind="foreach: myFieldList"> 
      <tr> 
       <td><input data-bind="value: name" /></td> 
       <td><input data-bind="value: value" /></td> 
       <td><span class="removeVar" data-bind="click: removeProperty">Remove property</span></td> 
      </tr> 
     </tbody> 
    </table> 
    <p> 
     <span id="addVar" data-bind="click: addProperty">Add Property</span> 
    </p> 
<textarea name="tasks" data-bind="value: ko.toJSON(myFieldList)"></textarea> 

这里是JS:

<script type="text/javascript"> 

    function dynamicProperty(name, value) { 
     var self = this; 
     this.name = name; 
     this.value = value; 
    } 

    function fieldModel() { 
     var self = this;   
//start with 2 empty properties 
     self.myFieldList = ko.observableArray([ 
      new dynamicProperty("", ""), 
      new dynamicProperty("","") 
     ]); 

     var noTracker = self.myFieldList.length; 

     self.removeProperty = function (dynamicProperty) { 
      self.myFieldList.remove(dynamicProperty); 
     } 

     self.addProperty = function() { 
      noTracker++; 
      self.myFieldList.push(new dynamicProperty(this.name,this.value)); 
     } 
    } 

    ko.applyBindings(fieldModel); 

</script> 

我在textarea的得到的是这样的输出:

[{"name":"test name 1","value":"test value 1"},{"name":"test name 2","value":"test value 2"}] 

什么我想要的是这样的输出:

{"test name 1":"test value 1","test name 2":"test value 2"} 

我担心这是相当无足轻重的,但在我的防守中,我对JS和Knockout非常陌生,所以你可以提供的任何帮助都将受到极大的赞赏。谢谢。

回答

1

你可能想要做这样的事情来完成它。
例子:https://jsfiddle.net/9aLvd3uw/79/
HTML

<table> 
     <thead> 
      <tr> 
       <th>Property Name</th> 
       <th>Property Value</th> 
       <th></th> 
      </tr>    
     </thead> 
     <tbody data-bind="foreach: myFieldList"> 
      <tr> 
       <td><input data-bind="textInput: name" /></td> 
       <td><input data-bind="textInput: value" /></td> 
       <td><span class="removeVar" data-bind="click: removeProperty">Remove property</span></td> 
      </tr> 
     </tbody> 
    </table> 
    <p> 
     <span id="addVar" data-bind="click: addProperty">Add Property</span> 
    </p> 
<textarea name="tasks" data-bind="value: myFieldList2"></textarea> 

JS

function dynamicProperty(name, value) { 
    var self = this; 
    self.name = ko.observable(name || ''); 
    self.value = ko.observable(value || ''); 
} 

function fieldModel() { 
    var self = this; 
    self.name = ko.observable(); 
    self.value = ko.observable(); 
    self.myFieldList = ko.observableArray([ 
     new dynamicProperty("test_name_1", "test value 1"), 
     new dynamicProperty("test_name_2","test value 2") 
    ]); 

    var noTracker = self.myFieldList.length; 

    self.myFieldList2 = ko.computed(function() { 
     var string = '{'; 
     ko.utils.arrayForEach(self.myFieldList(), function (item) { 
      string += item.name() + ': ' + item.value() + ','; 
     }); 
     string = string.replace(/,\s*$/, ""); 
     string+='}'; 
     return string; 
    }); 

    self.removeProperty = function (dynamicProperty) { 
     self.myFieldList.remove(dynamicProperty); 
    } 

    self.addProperty = function() { 
     noTracker++; 
     self.myFieldList.push(new dynamicProperty('','')); 
    } 
} 

ko.applyBindings(fieldModel); 
+0

正是我所需要的。我已经稍微修改它以包含字符串引号 - string + ='“'+ item.name()+'”:“'+ item.value()+'”,'; - 它只是我想要的,谢谢。 – cjashwell

1

你需要的是一个“减速器”。

一个简单的(幼稚太)的实现是这样的:

function reduce(input, step, init) { 
    for(var i = 0; i < input.length; i++) { 
    init = step(init, input[i]); 
    } 

    return init; 
} 

然后调用它像这样:

var in = [{"name":"test name 1","value":"test value 1"},{"name":"test name 2","value":"test value 2"}]; 

var out = reduce(in, function(result, item) { 
    result[item.name] = item.value; 
    return result; 
}, {}); 

console.log(out); 

它所做的是,它通过您的数组进行迭代,并且“积累”单个项目中每个步骤的结果。可能是数组中数字的总和,其中“累加器”是数字而不是对象。

我建议你不要自己写,而应该使用lodash,它带有一个_.reduce函数进行了优化。

+1

还有在'Array.prototype'一个'reduce'。您可以像这样使用它:'dataArray.reduce(function(previous,current){previous} {current.name] = current.value; return previous; },{});'(https:// developer。 mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) – user3297291

+0

你是完全正确的。 IE9 +在大多数项目中应该可以安全使用。 –