2017-11-22 4 views
0

KnockoutJS를 처음 사용합니다. 페이지는이 자료 구조는 작은 조각으로 갈라진다 및 데이터의 이러한 덩어리 구성 요소에 전달되는 KnockoutJS 구성 요소에서 업데이트 된 데이터 어셈블하기

  • 을 프론트 엔드에 전달되는 복잡한 데이터 구조를로드

    1. : 나는 다음과 같은 방식으로 작동하는 응용 프로그램을 가지고
    2. 사용자는

    내가 가지고있는 백엔드에 전달해야한다 버튼 업데이트 복잡한 데이터 구조를 클릭시 데이터

  • 의 덩어리를 편집 할 구성 요소와 상호 작용 네 번째 단계의 문제. 필자는 설명서를 읽었지만 업데이트 된 데이터를 얻는 방법을 알지 못했습니다. 여기

    는 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>