2016-04-28 97 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 +在大多數項目中應該可以安全使用。 –