一旦我从 promise 中获得价值,就渲染 li 价值
Render li value once I got value from promise
我有一个呈现列表的模板。其中两个值需要进行地理编码(从我想显示地址的经纬度值开始)。我在控制台中有值,但 li 显示 [object Promise]。我知道渲染不是同步的,所以我尝试使用一个标志来仅在我有值时显示 li,但它们从未显示过。基本上我明白问题是什么,但无法弄清楚如何重新排列代码以使其工作。
这里的模板:
<div v-if="!isLoading && Object.keys(currentActivity).length > 0">
<ul
v-for="value in currentActivity"
:key="value.id"
class="listValues"
>
<li>Attività:
<b>{{ value.activity.activityName }} - {{ value.related_activity }}
</b>
</li>
<li>Inizio: <b>{{ value.start }}</b></li>
<li>Fine: <b>{{ value.end }}</b></li>
<li>Durata: <b>{{ timeConvert(value.duration) }}</b></li>
<li v-if="!isGeocoding">Punto di partenza: <b>{{ getAddress(getLatLng(value.starting_point)) }}</b></li>
<li v-if="!isGeocoding">Punto di arrivo: <b>{{ getAddress(getLatLng(value.arrival_point)) }}</b></li>
<li>Stato: <b>{{ value.status | stato }}</b></li>
<li>Distanza: <b>{{ kmCovert(value.travel_distance) }}</b></li>
<li>Kcal consumate: <b>{{ value.kcal }}</b></li>
<li>Produzione di Co2: <b>{{ value.co2 }}</b></li>
<li>Costo: <b>{{ value.cost }} €</b></li>
<li>Utente:
<router-link :to="{name: 'SchedaUtente', params: { userId: value.owner.id }}">
<b style="text-decoration: underline;">
{{ value.owner.username }}
</b>
</router-link>
</li>
</ul>
</div>
我也尝试将条件放在 div 中(与 !isLoading && Object.keys(currentActivity).length > 0
一起),但这样整个列表不会显示。
在我设置的数据中,除其他外,isGeocoding: true
涉及的其他方法:
async mounted() {
await this.getActivityData()
},
methods: {
getActivityData() {
this.isLoading = true
const currentUser = this.$store.getters.currentProfile.user
this.currentUser = currentUser
console.log('current activity scheda attivita: ', this.currentActivity)
console.log('current user scheda attivita: ', currentUser)
this.isLoading = false
console.log('is loading after ', this.isLoading)
},
getLatLng(sridPoint) {
const arrayLatLng = sridPoint.replace('SRID=4326;POINT (', '').replace(')', '').split(' ')
const latLng = { lat: parseFloat(arrayLatLng[1]), lng: parseFloat(arrayLatLng[0]) }
return latLng
},
async getAddress(latLng) {
await this.$gmapApiPromiseLazy().then(() => {
const geocodeAddress = new Promise(function(resolve, reject) {
// eslint-disable-next-line no-undef
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ 'location': latLng }, function(results, status) {
if (status === 'OK') {
if (results.length > 0) {
resolve([results[0].formatted_address])
}
} else {
reject(new Error('Couldnt\'t find the location.'))
}
})
})
geocodeAddress.then(function(address) {
console.log(address)
this.isGeocoding = false
console.log('geocoding: ', this.isGeocoding)
return address
})
})
},
这样两个地址永远不会显示,如果我删除标志 isGeocoding,正如我之前所说,我在控制台中获得了值,但在模板中获得了 [object Promise]。
有人可以帮忙吗?
谢谢
x
Vue 似乎不能很好地处理返回 Promise 的方法。
为了给你这个解决方法,我付出了很多努力:(你可以稍后感谢我:D)
创建一个组件并将其包含在每一行中,将方法输入传递到内部,并让它进行计算:
演示:https://jsfiddle.net/niccord/rk1ec6au/
要点:
Table:
<address-point :point="point"></address-point>
组件:
methods: {
getAddress() {
return this.$gmapApiPromiseLazy().then(() => {
// assign the value to the data variable! (this is when the trick happens)
this.addr = this.point + 10
})
}
},
mounted () {
// call the async method
this.getAddress()
}
我是这样工作的:
- 我添加了响应式数据属性来表示起始地址和到达地址,并添加了两个常量以具有更多可读代码,因此在数据中:
startingAddress: null,
arrivalAddress: null,
start: null,
end: null
- 我在模板中引用了这些属性,而不是承诺:
<li v-if="startingAddress">Punto di partenza: <b>{{ this.startingAddress }}</b></li>
<li v-if="arrivalAddress">Punto di arrivo: <b>{{ this.arrivalAddress }}</b></li>
这样我就可以摆脱布尔标志 isGeocoding,因为我可以简单地检查各个地址属性。
- 然后我在 getActivityData 函数中调用了 getAddress 承诺,而不是从模板中调用。然后我可以响应那些设置相应地址属性的承诺。
async getActivityData() {
this.isLoading = true
const currentUser = this.$store.getters.currentProfile.user
this.currentUser = currentUser
console.log('current activity scheda attivita: ', this.currentActivity)
this.start = this.getLatLng(this.currentActivity.activity.starting_point)
this.end = this.getLatLng(this.currentActivity.activity.arrival_point)
console.log('PROMISE',this.getAddress(this.start))
const [startingAddress, arrivalAddress] = await
Promise.all([this.getAddress(this.start), this.getAddress(this.end)])
this.startingAddress = startingAddress
this.arrivalAddress = arrivalAddress
this.isLoading = false
},
我在 mounted 中调用了这个函数:
async mounted() {
await this.getActivityData()
},
- 我使其他两个函数更具可重用性,因此:
getLatLng(sridPoint) {
const arrayLatLng = sridPoint.replace('SRID=4326;POINT (', '').replace(')', '').split(' ')
const latLng = { lat: parseFloat(arrayLatLng[1]), lng: parseFloat(arrayLatLng[0]) }
return latLng
},
getAddress(latLng) {
return this.$gmapApiPromiseLazy().then(() => {
const geocodeAddress = new Promise(function(resolve, reject) {
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ 'location': latLng }, (results, status) => {
if (status === 'OK') {
if (results.length > 0) {
resolve(latLng = results[0].formatted_address)
} else {
reject(new Error('Couldnt\'t find the location.'))
}
}
})
})
return geocodeAddress.then(function(address) {
console.log(address)
return address
})
})
}
注意 getAddress 函数开头和结尾的两个 return,我之前没有注意到:
return this.$gmapApiPromiseLazy()....
return 地理编码地址....
x
我有一个呈现列表的模板。其中两个值需要进行地理编码(从我想显示地址的经纬度值开始)。我在控制台中有值,但 li 显示 [object Promise]。我知道渲染不是同步的,所以我尝试使用一个标志来仅在我有值时显示 li,但它们从未显示过。基本上我明白问题是什么,但无法弄清楚如何重新排列代码以使其工作。 这里的模板:
<div v-if="!isLoading && Object.keys(currentActivity).length > 0">
<ul
v-for="value in currentActivity"
:key="value.id"
class="listValues"
>
<li>Attività:
<b>{{ value.activity.activityName }} - {{ value.related_activity }}
</b>
</li>
<li>Inizio: <b>{{ value.start }}</b></li>
<li>Fine: <b>{{ value.end }}</b></li>
<li>Durata: <b>{{ timeConvert(value.duration) }}</b></li>
<li v-if="!isGeocoding">Punto di partenza: <b>{{ getAddress(getLatLng(value.starting_point)) }}</b></li>
<li v-if="!isGeocoding">Punto di arrivo: <b>{{ getAddress(getLatLng(value.arrival_point)) }}</b></li>
<li>Stato: <b>{{ value.status | stato }}</b></li>
<li>Distanza: <b>{{ kmCovert(value.travel_distance) }}</b></li>
<li>Kcal consumate: <b>{{ value.kcal }}</b></li>
<li>Produzione di Co2: <b>{{ value.co2 }}</b></li>
<li>Costo: <b>{{ value.cost }} €</b></li>
<li>Utente:
<router-link :to="{name: 'SchedaUtente', params: { userId: value.owner.id }}">
<b style="text-decoration: underline;">
{{ value.owner.username }}
</b>
</router-link>
</li>
</ul>
</div>
我也尝试将条件放在 div 中(与 !isLoading && Object.keys(currentActivity).length > 0
一起),但这样整个列表不会显示。
在我设置的数据中,除其他外,isGeocoding: true
涉及的其他方法:
async mounted() {
await this.getActivityData()
},
methods: {
getActivityData() {
this.isLoading = true
const currentUser = this.$store.getters.currentProfile.user
this.currentUser = currentUser
console.log('current activity scheda attivita: ', this.currentActivity)
console.log('current user scheda attivita: ', currentUser)
this.isLoading = false
console.log('is loading after ', this.isLoading)
},
getLatLng(sridPoint) {
const arrayLatLng = sridPoint.replace('SRID=4326;POINT (', '').replace(')', '').split(' ')
const latLng = { lat: parseFloat(arrayLatLng[1]), lng: parseFloat(arrayLatLng[0]) }
return latLng
},
async getAddress(latLng) {
await this.$gmapApiPromiseLazy().then(() => {
const geocodeAddress = new Promise(function(resolve, reject) {
// eslint-disable-next-line no-undef
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ 'location': latLng }, function(results, status) {
if (status === 'OK') {
if (results.length > 0) {
resolve([results[0].formatted_address])
}
} else {
reject(new Error('Couldnt\'t find the location.'))
}
})
})
geocodeAddress.then(function(address) {
console.log(address)
this.isGeocoding = false
console.log('geocoding: ', this.isGeocoding)
return address
})
})
},
这样两个地址永远不会显示,如果我删除标志 isGeocoding,正如我之前所说,我在控制台中获得了值,但在模板中获得了 [object Promise]。 有人可以帮忙吗? 谢谢 x
Vue 似乎不能很好地处理返回 Promise 的方法。
为了给你这个解决方法,我付出了很多努力:(你可以稍后感谢我:D)
创建一个组件并将其包含在每一行中,将方法输入传递到内部,并让它进行计算:
演示:https://jsfiddle.net/niccord/rk1ec6au/
要点:
Table:
<address-point :point="point"></address-point>
组件:
methods: {
getAddress() {
return this.$gmapApiPromiseLazy().then(() => {
// assign the value to the data variable! (this is when the trick happens)
this.addr = this.point + 10
})
}
},
mounted () {
// call the async method
this.getAddress()
}
我是这样工作的:
- 我添加了响应式数据属性来表示起始地址和到达地址,并添加了两个常量以具有更多可读代码,因此在数据中:
startingAddress: null,
arrivalAddress: null,
start: null,
end: null
- 我在模板中引用了这些属性,而不是承诺:
<li v-if="startingAddress">Punto di partenza: <b>{{ this.startingAddress }}</b></li>
<li v-if="arrivalAddress">Punto di arrivo: <b>{{ this.arrivalAddress }}</b></li>
这样我就可以摆脱布尔标志 isGeocoding,因为我可以简单地检查各个地址属性。
- 然后我在 getActivityData 函数中调用了 getAddress 承诺,而不是从模板中调用。然后我可以响应那些设置相应地址属性的承诺。
async getActivityData() {
this.isLoading = true
const currentUser = this.$store.getters.currentProfile.user
this.currentUser = currentUser
console.log('current activity scheda attivita: ', this.currentActivity)
this.start = this.getLatLng(this.currentActivity.activity.starting_point)
this.end = this.getLatLng(this.currentActivity.activity.arrival_point)
console.log('PROMISE',this.getAddress(this.start))
const [startingAddress, arrivalAddress] = await
Promise.all([this.getAddress(this.start), this.getAddress(this.end)])
this.startingAddress = startingAddress
this.arrivalAddress = arrivalAddress
this.isLoading = false
},
我在 mounted 中调用了这个函数:
async mounted() {
await this.getActivityData()
},
- 我使其他两个函数更具可重用性,因此:
getLatLng(sridPoint) {
const arrayLatLng = sridPoint.replace('SRID=4326;POINT (', '').replace(')', '').split(' ')
const latLng = { lat: parseFloat(arrayLatLng[1]), lng: parseFloat(arrayLatLng[0]) }
return latLng
},
getAddress(latLng) {
return this.$gmapApiPromiseLazy().then(() => {
const geocodeAddress = new Promise(function(resolve, reject) {
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ 'location': latLng }, (results, status) => {
if (status === 'OK') {
if (results.length > 0) {
resolve(latLng = results[0].formatted_address)
} else {
reject(new Error('Couldnt\'t find the location.'))
}
}
})
})
return geocodeAddress.then(function(address) {
console.log(address)
return address
})
})
}
注意 getAddress 函数开头和结尾的两个 return,我之前没有注意到:
return this.$gmapApiPromiseLazy()....
return 地理编码地址....
x