2016-11-12 6 views
3

VueJS 렌더링에 문제가 있습니다. 아약스 당 데이터를 가져 왔습니다. 초기 렌더링시 테이블 행이 올바르게 렌더링되지만 업데이트 된 요소를 다시 렌더링 할 때 올바르게 렌더링되지 않습니다. 당신이 볼 수 있듯이, 행 1 잘 렌더링 Rendered TableVueJS 2 재 렌더링 테이블

:

여기 사진입니다. 그러나 다시 렌더링 된 2 번 행에서는 tds가 반전됩니다.

var renderings = new Vue({ 
el: '#renderings', 

data: function() { 
    return { 
     hasUnprocessedRenderings: false, 
     renderings: {} 
    }; 
}, 

methods: { 
    clearData: function() { 
     this.renderings = {}; 
    }, 

    updateData: function() { 

     this.$http.get('http://some-url.com/renderings').then(function (response) { 
      this.renderings = response.body.renderings; 
      this.hasUnprocessedRenderings = response.body.hasUnprocessedRenderings; 

      if (this.hasUnprocessedRenderings) { 
       setTimeout(this.updateData, 10000); 
      } 
     }); 

    } 
}, 

mounted: function() { 
    this.updateData(); 
} 

}); 

내 HTML :

여기 내 코드의

<div id="renderings"> 
<table class="table table-striped table-hover table-bordered" style="margin bottom: 0;"> 
<thead> 
<tr> 
    <th>Personalisierung</th> 
    <th>Format</th> 
    <th>Download</th> 
    <th></th> 
</tr> 
</thead> 
<tbody> 
<template v-for="rendering in renderings"> 
    <tr> 
     <td>{{rendering.personalizationName}}</td> 
     <td>{{rendering.renderTypeName}}</td> 
     <template v-if="rendering.DOCUMENT_URL"> 
      <td><a :href="rendering.DOCUMENT_URL">{{rendering.DOCUMENT_URL}}</a></td> 
      <td> 
       <ul class="list-inline" style="margin-bottom: 0;"> 
        <li><a :href="'http://some-url.com?pid='+rendering.PROCESS_ID" title="refresh"><i class="fa fa-refresh" aria-hidden="true"></i></a></li> 
        <li><a :href="'http://some-url.com?pid='+rendering.PROCESS_ID" title="delete"><i class="fa fa-trash-o" aria-hidden="true"></i></a></li> 
       </ul> 
      </td> 
     </template> 
     <template v-else> 
      <td colspan="2" style="text-align: center;"> 
       <i class="fa fa-cog fa-spin fa-fw"></i> 
       <span>In Bearbeitung..</span> 
      </td> 
     </template> 
    </tr> 
</template> 
</tbody> 
</table> 
</div> 

그래서 내 질문 : 어떻게 행이 올바르게 다시 렌더링지고 있음을, 해결할 수 있습니까?

도움 주셔서 감사합니다. :-)

수정 # 1 : 다음은 문제도 발생하는 jsfiddle,이다 : https://jsfiddle.net/dt1kt06g/

+0

템플릿의 구문 오류 (' Aletheios

+0

지금 jsfiddle을 코드와 데이터로 추가하고 구문 오류를 수정했습니다. 문제가 발생합니다. – Hendrik

답변

0

이 동작 뷰의 가상 DOM 알고리즘의 최적화의 부작용 인 것처럼 보인다. 업데이트가 발생하면 Vue는 요소 이동을 최소화하려고 시도하고 대신 기존 DOM 노드를 재사용 및 패치합니다. 당신이 데이터를 업데이트 한 후 귀하의 JSFiddle에서 생성 된 HTML을 검사 할 때

, 당신은 우리에게 <td> 요소가 잘못에서 재사용 된 것을 힌트를 제공하는 두 번째 <tr>의 마지막 <td> 여전히 속성 colspan="2" style="text-align: center;"을 가지고 있음을 알 수 있습니다 이전에 렌더링 된 "진행 중"셀 v-else에 있습니다. (이것이 Vue의 버그로 특징 지어 질 수 있는지 확실하지 않습니다 ...)

어쨌든,이 문제에 대한 해결 방법이 있습니다 : 노드 diffing 알고리즘에 힌트를주는 특별한 key 속성이 Vue에 있습니다. 요소 (see documentation)를 처리하십시오. 당신의 예에서, v-else 지점에 <td>에 키를 추가하면 충분하다 :

<template v-else> 
    <td colspan="2" style="text-align: center;" :key="rendering.PROCESS_ID"> 
    ... 

Here`s 당신의 JSFiddle의 fixed version을.

+0

Ahhhh 대단히 감사합니다. :-) 나는 또한 두 번째'template'을 제거하고'v-else'를'tr'에 직접 넣으면 잘 작동하는 것으로 나타났습니다. – Hendrik

+0

@Hendrik 't -d'에 직접'v-else '가 있다고해도, Vue는 요소를 재사용하지 않고 다시 만들어야합니다. – Aletheios

0

문제는 아마 당신이 각각의 새로운 값 Vue.set(this.renderings, key, value)을 사용해야 하나 this.renderings = {...}

할당하려면 개체 속성을 사용하면 객체에 데이터를 할당하는 방식과 관련된, 또는 this.renderings = Object.assign({}, this.renderings, newData)

이 완벽하게 작동하거나 https://vuejs.org/v2/guide/reactivity.html