2017-11-28 27 views
0

하위 구성 요소에서 올바른 개체를 업데이트하는 데 문제가 있습니다.Vue.js - 하위 구성 요소를 사용하여 패턴을 업데이트하거나 실행 취소합니다.

내 설정은 다음과 같습니다. 대부분의 데이터를 표시하거나 편집하려는 하나의 ul 목록입니다. "li"의 한 부분에는 데이터의 일부분 (해당 개체에 연결된 리소스 목록)을 표시하고 새 리소스를 처리하는 하위 구성 요소가 있습니다.

사용자가 행의 편집 모드를 활성화 한 다음 업데이트 및 취소 버튼을 사용하기를 원합니다.

내가 직면 한 문제는 편집해야하는 개체를 파악한 다음 저장하는 것입니다. 지금 내가하고있는 일은 사용자가 편집 모드에 있지 않을 때 실제 행 데이터가 표시되는 동안 입력 컨트롤의 모델로 사용하는 mutableRow에 행의 데이터를 복사하려고하는 것입니다. 업데이트 메서드에서 나는 DB에 게시하고 행 개체를 업데이트했습니다.

ul 
    li(v-for="row in rows") 
    p(v-if="!row.editing") {{ row.name }} 
    input(v-else, v-model="mutableRow.name") 
    resources(:row="row") 
    button(v-if="!row.editing") Start edit 
    template(v-else) 
     button Update 
     button Cancel 

올바른 방법일까요? 그렇다면 하위 구성 요소로 전송되는 소품을 어떻게 처리해야합니까? 나는 이것을 통해 mutableRow를 가져 오는 것을 시도했다. $ parent.mutableRow, 나는 "resource (: row ="row ")"를 v-if로 바꾸려고 시도하고 편집 모드에서 mutableRow를 보낸다. 구성 요소에서 두 객체를 모두 변경하는 방법.

내가 사용할 수있는 또 다른 패턴이 있습니까?

+0

는 I는'editing' 상태 및 수정 값은 요소의 내부 인 경우, 전체 '성분 li' 만들 것이다. 업데이트는 이벤트를 발생시키고 취소는 편집 값을 재설정합니다. –

+0

내가 무슨 뜻인지 정확히 이해하지 못해서 모범을 보일 수 있겠습니까? :/ 전체 구성 요소가 하나의 구성 요소 여야한다는 것을 의미합니까? 문제는 많은 다른 입력 필드가 있으므로 많은 메소드와 템플릿이 있으므로 작은 부분으로 만들려고했습니다. – Solander

+0

데이터의 모습을 보여줄 수 있습니까? 한 구성 요소 안에 더 작은 구성 요소가 있어야 할 수도 있습니다. –

답변

1

"가변 행"문제는 row 대신 rows[index]을 전달하여 해결할 수 있다고 생각합니다. 어쨌든 .sync을 만들기 위해서는 그것이 필요합니다.

아래의 예제는 주석에서 제안한 내용을 구현합니다. 데이터의 자체 복사본과 편집 모드에 대한 자체 컨트롤이있는 단일 구성 요소입니다. 편집을 시작하면 보조 데이터가 로컬 데이터에 복사됩니다. 업데이트를 클릭하면 이벤트가 발생하고 부모 (sync 경유)는 편집 된 데이터를 행에 복사합니다. 취소를 클릭하면 이벤트가 방출되지 않고 편집이 끝납니다.

new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    rows: [{ 
 
     name: "Test", 
 
     thingy: 4, 
 
     resources: [{ 
 
     title: "Title", 
 
     price: 5000 
 
     }] 
 
    }] 
 
    }, 
 
    components: { 
 
    rowEditor: { 
 
     template: '#row-editor-t', 
 
     props: ['row'], 
 
     data() { 
 
     return { 
 
      editing: false, 
 
      localRow: null 
 
     }; 
 
     }, 
 
     methods: { 
 
     startEditing() { 
 
      this.editing = true; 
 
      this.localRow = JSON.parse(JSON.stringify(this.row)); 
 
     }, 
 
     stopEditing() { 
 
      this.editing = false; 
 
     }, 
 
     update() { 
 
      this.$emit('update:row', this.localRow); 
 
      this.stopEditing(); 
 
     }, 
 
     cancel() { 
 
      this.stopEditing(); 
 
     } 
 
     } 
 
    } 
 
    } 
 
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script> 
 
<div id="app"> 
 
    <ul> 
 
    <li v-for="row, index in rows" is="row-editor" :row.sync="rows[index]"> 
 
    </li> 
 
    </ul> 
 
</div> 
 

 
<template id="row-editor-t"> 
 
    <li> 
 
    <div v-if="editing"> 
 
     <input v-model="localRow.name"> 
 
     <div v-for="resource in localRow.resources"> 
 
     <input v-model="resource.title"><input v-model="resource.price"> 
 
     </div> 
 
    </div> 
 
    <div v-else> 
 
     {{row.name}} 
 
     <div v-for="resource in row.resources"> 
 
     {{resource.title}}: {{resource.price}} 
 
     </div> 
 
    </div> 
 
    <div v-if="editing"> 
 
     <button type="button" @click="update">Update</button> 
 
     <button type="button" @click="cancel">Cancel</button> 
 
    </div> 
 
    <button v-else @click="startEditing">Start edit</button> 
 
    </li> 
 
</template> 
 

 
<!-- 
 
ul 
 
    li(v-for=" row in rows ") 
 
    p(v-if="!row.editing ") {{ row.name }} 
 
    input(v-else, v-model="mutableRow.name ") 
 
    resources(:row="row ") 
 
    button(v-if="!row.editing ") Start edit 
 
    template(v-else) 
 
     button Update 
 
     button Cancel 
 
-->

+0

완벽한 솔루션!이 코드를 사용하면 코드에서 문제를 발견하는 데 많은 도움이되었습니다. 모든 행을 구성 요소로 분리 한 다음 전체 구성 요소 하나만 사용하면 행,하지만 가장 큰 문제는 여전히 거기에 있었다. 나는 "this.mutableRow = Vue.util.extend ({}, this.row)"개체를 복사하는 데 사용하고있는, 얕은 복사본을 만든 것을 발견하고 그 이유는 나는 원래 객체의 "resources"배열을 수정하는 결과를 얻었습니다. 이제 jQuery.extend (true, {}, this.row)를 사용하여 딥 복사본을 만듭니다. jQuery 또는 JSON 파싱 트릭이 최고이지만이 방법이 효과적입니다. 감사! – Solander