2017-12-24 31 views
0

計算されたデータを使用してadd関数を使用してツリーを作成しようとしています。私はvuejsの公式ホームページでツリービューの例を使用し、それを作成した計算された関数と組み合わせましたが、それを実装する上で運がないことを発見しました。私はすでに4日間この問題を解決しようとしていますが、まだ運がないので、私はここで助けを求めています。vue.js - 生のjsonからネストされた配列を使用すると、再帰コンポーネントが更新されない

リストの最後にある「+」をクリックすると、addChild関数の呼び出しがトリガーされ、正常にデータが追加されます。データは追加されますが、再帰コンポーネントは反応しません。

https://jsfiddle.net/znedj1ao/9/

var data2 = [{ 
 
    "id": 1, 
 
    "name":"games", 
 
    "parentid": null 
 
    }, 
 
    { 
 
    "id": 2, 
 
    "name": "movies", 
 
    "parentid": null 
 
    }, 
 
    { 
 
    \t "name": "iron-man", 
 
    "id": 3, 
 
    "parentid": 2 
 
    }, 
 
    { 
 
    "id": 4, 
 
    "name": "iron-woman", 
 
    "parentid": 3 
 
    } 
 
] 
 

 
// define the item component 
 
Vue.component('item', { 
 
    template: '#item-template', 
 
    props: { 
 
    model: Object 
 
    }, 
 
    data: function() { 
 
    return { 
 
     open: false 
 
    } 
 
    }, 
 
    computed: { 
 
    isFolder: function() { 
 
     return this.model.children && 
 
     this.model.children.length 
 
    } 
 
    }, 
 
    methods: { 
 
    toggle: function() { 
 
     if (this.isFolder) { 
 
     this.open = !this.open 
 
     } 
 
    }, 
 
    changeType: function() { 
 
     if (!this.isFolder) { 
 
     Vue.set(this.model, 'children', []) 
 
     this.addChild() 
 
     this.open = true 
 
     } 
 
    }, 
 
    addChild: function() { 
 
     this.model.children.push({ 
 
     name: 'My Tres', 
 
    \t \t \t \t children: [ 
 
    \t \t \t { name: 'hello' }, 
 
    \t \t \t { name: 'wat' } 
 
     ] 
 
     }) 
 

 
    } 
 
    } 
 
}) 
 

 
// boot up the demo 
 
var demo = new Vue({ 
 
    el: '#demo', 
 
    data: { 
 
    treeData2: data2 
 
    }, 
 
    computed: { 
 
    nestedInformation: function() {  
 
      var a= this.nestInformation(data2); 
 
      return a; 
 
     } 
 
    
 
    }, 
 
    methods: 
 
    { 
 
     nestInformation: function(arr, parent){ 
 
      var out = [] 
 
    for(var i in arr) { 
 
     if(arr[i].parentid == parent) { 
 
      var children = this.nestInformation(arr, arr[i].id) 
 

 
      if(children.length) { 
 
       arr[i].children = children 
 
      } 
 
      out.push(arr[i]) 
 
     } 
 
    } 
 
    return out 
 
    } 
 
    } 
 
})
<!-- item template --> 
 
<script type="text/x-template" id="item-template"> 
 
    <li> 
 
    <div 
 
     :class="{bold: isFolder}" 
 
     @click="toggle" 
 
     @dblclick="changeType"> 
 
     {{model.name}} 
 
     <span v-if="isFolder">[{{open ? '-' : '+'}}]</span> 
 
    </div> 
 
    <ul v-show="open" v-if="isFolder"> 
 
     <item 
 
     class="item" 
 
     v-for="model in model.children" 
 
     :model="model"> 
 
     </item> 
 
     <li class="add" @click="addChild">+</li> 
 
    </ul> 
 
    </li> 
 
</script> 
 

 
<p>(You can double click on an item to turn it into a folder.)</p> 
 

 
<!-- the demo root element --> 
 
<ul id="demo"> 
 
    <item 
 
    class="item" 
 
    :model="nestedInformation[1]"> 
 
    </item> 
 
</ul>

+0

私はVueのエキスパートではありませんが、プッシュを使用して配列に要素を追加しても、追加されたプロパティが反応するとは限りません。 '$ set'や' Vue.set() 'を試してみてください。しかし、私は本当によくわからない。 –

+0

私はすでにそれが動作しないことを試みた。 https://jsfiddle.net/3p0j5sgy/1368/ここで確認できます。唯一の違いは、既に親子構造になっているデータを渡していることです。 – Johji

+0

私の問題は私のデータは生ではないので、まずツリー構造に変換して渡す必要があります。 – Johji

答えて

2

上記commentAbdullah Khanlinkedには言うことをVue.jsドキュメント:による近代JavaScriptを制限するために、再度

を、Vueのはできませんプロパティの追加または削除を検出する

ただし、プロパティの追加は正確にが何であるかを、あなたのnestInformation方法でやっている:

if(children.length) { 
    arr[i].children = children 
} 

結果は、各オブジェクトのchildrenプロパティが反応しない、その際にこのArrayであるということですaddChildにプッシュされると、UIで再レンダリングがトリガーされません。

アレイを作成するときは、反応性のプロパティになるように解決策が使用されます(Vue.set)。 nestInformation方法で関連するコードは次のように更新する必要があります。

if (children.length) { 
    Vue.set(arr[i], 'children', children); 
} 

私はフォークや参考のためにあなたのfiddleを変更しています。

関連する問題