2016-04-28 9 views
0

内部でホストされているサービスにJSONとして投稿できるオブジェクトをユーザーが作成できるHTMLページを作成したいとします(Chrome Advanced Rest Client )。ユーザーはプロパティを追加および削除できる必要があります。オブジェクトからプロパティを追加/削除するノックアウトやその他のJavaScript

各プロパティは '名前'と '値'のプロパティを持つオブジェクトのように扱われるため、モデルが正しくありません。私は、プロパティを持つオブジェクトではなく、オブジェクトの配列で終わります。ここで

は、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> 

私は何をテキストエリアに取得すると、このように出力されます:

[{"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://開発者。 mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) – user3297291

+0

あなたはまったく正しいです。 IE9 +は、ほとんどのプロジェクトで安全に使用する必要があります。 –

関連する問題