2017-11-22 3 views
0

KnockoutJSを初めて使用しています。ページが、このデータ構造は、より小さなチャンクに分割され、これらのデータのチャンクがコンポーネントに渡され KnockoutJSコンポーネントから更新されたデータを組み立てる

  • をフロントエンドに渡される複雑なデータ構造をロードされている

    1. : 私は次のように動作するアプリを持っています
    2. ユーザーは、私が持っている

    をバックエンドに渡されるべき複雑なデータ構造を更新]ボタンをクリックすると、データ

  • の塊を編集するためのコンポーネントと対話します第4ステップのトラブル。私はドキュメントを読んできましたが、更新されたデータをどのように入手するのか分かりませんでした。ここ

    はJSFiddleある:ここhttps://jsfiddle.net/vrggyf45

    は、スニペットに同じコードです。私が試したことの質問の一番下を見てください。

    ko.components.register('firstComponent', { 
     
        viewModel: function(params) { 
     
        var self = this; 
     
        self.firstComponentValue = ko.observable(params.firstComponentValue); 
     
        }, 
     
        template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: firstComponentValue, valueUpdate: \'afterkeydown\'"></div>' 
     
    }); 
     
    
     
    ko.components.register('secondComponent', { 
     
        viewModel: function(params) { 
     
        var self = this; 
     
        self.secondComponentValue = ko.observable(params.secondComponentValue); 
     
        }, 
     
        template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: secondComponentValue, valueUpdate: \'afterkeydown\'"></div>' 
     
    }); 
     
    
     
    
     
    var json = '{"items":[{"componentName":"firstComponent","firstComponentValue":"somevalue"},{"componentName":"secondComponent","secondComponentValue":"someothervalue"}]}'; 
     
    var data = JSON.parse(json); 
     
    var mainVM = {}; 
     
    mainVM.items = ko.observableArray(
     
        ko.utils.arrayMap(data.items, 
     
        function(item) { 
     
         return ko.observable(item); 
     
        })); 
     
    
     
    ko.applyBindings(mainVM); 
     
    
     
    $('input[type=button]').click(function() { 
     
        var updatedData = ko.dataFor(document.getElementById('main')); 
     
        //get updated json somehow? 
     
        console.log(data); 
     
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
     
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
     
    
     
    <div id="main"> 
     
        <pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre> 
     
        <div data-bind="foreach: {data: items, as: 'item'}"> 
     
        <hr> 
     
        <div data-bind="component: {name:componentName, params: item}"> 
     
        </div> 
     
        </div> 
     
        <hr> 
     
        <input type="button" value="post data"> 
     
    </div>

    私はちょうどko.dataFor($("#rootElement"))を使用し、バックエンドに送信している可能性が単一のビューモデルを持っていた場合。しかし、私はコンポーネントを使用しようとしており、彼らは独自のビューモデルを持っています。それらはルートビューモデルには接続されていません。私はjQueryでそれらをすべて見つけてko.dataForを使用することができましたが、それは私に大きなハックのように見えます。 メインビューモデルのコンポーネントを含め、すべてのビューモデルを定義することもできますが、コンポーネントの種類が無用になります。

    また、コンポーネントのviewmodelsコンストラクタを変更して入力データを変更し、観測値で値をオーバーライドしようとしましたが、ハックのように思えます。

    ko.componentsのような機能や、すべてのリビングビューモデルを与えることができる機能はありますか?

  • 答えて

    1

    オブザーバブルをコンポーネントに渡すことができます。その結果、編集内容はすぐに親オブジェクトに反映されます。 ko.mappingは、プレーンなJSオブジェクトをオブザーバブルに変換するのに便利です。その後、データを戻す場合は、ko.toJS()です。

    ko.components.register('firstComponent', { 
     
        viewModel: function(params) { 
     
        var self = this; 
     
        self.firstComponentValue = params.firstComponentValue; 
     
        }, 
     
        template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: firstComponentValue, valueUpdate: \'afterkeydown\'"></div>' 
     
    }); 
     
    
     
    ko.components.register('secondComponent', { 
     
        viewModel: function(params) { 
     
        var self = this; 
     
        self.secondComponentValue = params.secondComponentValue; 
     
        }, 
     
        template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: secondComponentValue, valueUpdate: \'afterkeydown\'"></div>' 
     
    }); 
     
    
     
    
     
    var json = '{"items":[{"componentName":"firstComponent","firstComponentValue":"somevalue"},{"componentName":"secondComponent","secondComponentValue":"someothervalue"}]}'; 
     
    var data = JSON.parse(json); 
     
    var mainVM = {}; 
     
    mainVM.items = ko.mapping.fromJS(data.items); 
     
    
     
    ko.applyBindings(mainVM); 
     
    
     
    $('input[type=button]').click(function() { 
     
        var updatedData = ko.toJS(ko.dataFor(document.getElementById('main'))); 
     
        //Or, more simply: updatedData = ko.toJS(mainVM); 
     
        console.log(updatedData); 
     
    });
    <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> 
     
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
     
    
     
    <div id="main"> 
     
        <pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre> 
     
        <div data-bind="foreach: {data: items, as: 'item'}"> 
     
        <hr> 
     
        <div data-bind="component: {name:componentName, params: item}"> 
     
        </div> 
     
        </div> 
     
        <hr> 
     
        <input type="button" value="post data"> 
     
    </div>

    関連する問題