1
1
<template >
2
2
<div class =" item-view" v-if =" item" >
3
- <spinner :show =" !item" ></spinner >
4
3
<template v-if =" item " >
5
4
<div class =" item-view-header" >
6
5
<a :href =" item.url" target =" _blank" >
18
17
<div class =" item-view-comments" >
19
18
<p class =" item-view-comments-header" >
20
19
{{ item.kids ? item.descendants + ' comments' : 'No comments yet.'}}
20
+ <spinner :show =" loading" ></spinner >
21
21
</p >
22
- <ul v-if =" item.kids " class =" comment-children" >
22
+ <ul v-if =" !loading " class =" comment-children" >
23
23
<comment v-for =" id in item.kids" :id =" id" ></comment >
24
24
</ul >
25
25
</div >
@@ -37,22 +37,49 @@ function fetchItem (store) {
37
37
})
38
38
}
39
39
40
+ // recursively fetch all descendent comments
41
+ function fetchComments (store , item ) {
42
+ if (item .kids ) {
43
+ return store .dispatch (' FETCH_ITEMS' , {
44
+ ids: item .kids
45
+ }).then (() => Promise .all (item .kids .map (id => {
46
+ return fetchComments (store, store .state .items [id])
47
+ })))
48
+ }
49
+ }
50
+
51
+ function fetchItemAndComments (store ) {
52
+ return fetchItem (store).then (() => {
53
+ const { items , route } = store .state
54
+ return fetchComments (store, items[route .params .id ])
55
+ })
56
+ }
57
+
40
58
export default {
41
59
name: ' item-view' ,
42
60
components: { Spinner, Comment },
61
+ data () {
62
+ return {
63
+ loading: true
64
+ }
65
+ },
43
66
computed: {
44
67
item () {
45
68
return this .$store .state .items [this .$route .params .id ]
46
69
}
47
70
},
71
+ // on the server, only fetch the item itself
48
72
preFetch: fetchItem,
73
+ // on the client, fetch everything
49
74
beforeMount () {
50
- fetchItem (this .$store )
75
+ fetchItemAndComments (this .$store ).then (() => {
76
+ this .loading = false
77
+ })
51
78
}
52
79
}
53
80
</script >
54
81
55
- <style lang="stylus">
82
+ <style lang="stylus">
56
83
.item-view-header
57
84
background-color #f f f
58
85
padding 1.8em 2em 1em
@@ -71,17 +98,23 @@ export default {
71
98
background-color #f f f
72
99
margin-top 10px
73
100
padding 0 2em
74
-
101
+
75
102
.item-view-comments-header
76
103
margin 0
77
104
font-size 1.1em
78
105
padding 1em 0
106
+ position relative
107
+ .spinner
108
+ position absolute
109
+ top 0
110
+ right 0
111
+ bottom auto
79
112
80
113
.comment-children
81
114
list-style-type none
82
115
padding 0
83
116
margin 0
84
-
117
+
85
118
@media (max-width 600px )
86
119
.item-view-header
87
120
h1
0 commit comments