Оказывать ли ценность, как только я получил ценность от обещания - PullRequest
0 голосов
/ 28 октября 2019

У меня есть шаблон, отображающий список. Два из этих значений должны быть геокодированы (начиная с латинских значений, я хочу отобразить адрес). У меня есть значения в консоли, но li отображает [объект 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, как я уже говорил, я получилзначения в консоли, но [объект Promise] в шаблоне. Может кто-нибудь, пожалуйста, помогите? Спасибо х

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

Вот как я это заработал:

  1. Я добавил реактивные атрибуты данных, чтобы представить адреса начала и прибытия, и еще два const, чтобы иметь более читаемый код, поэтому в данных:
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, так как я могу просто проверитьотдельные атрибуты адреса.

Затем я вызвал обещания getAddress внутри функции getActivityData, а не из шаблона. Затем я мог бы ответить на эти обещания, чтобы установить соответствующие атрибуты адреса.
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
    },

Я вызвал эту функцию в смонтированном виде так:

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
   })
 })
}

Обратите внимание на два return s в начале и в конце функции getAddress,что я ранее пропустил:

  • вернуть это. $ gmapApiPromiseLazy () ....

  • вернуть geocodeAddress ....

x

0 голосов
/ 28 октября 2019

Vue, кажется, не очень хорошо работает с методами, возвращающими Обещание.

Я очень много работал, чтобы дать вам этот обходной путь: (вы можете поблагодарить меня позже: D)

Создайте компонент и включите его в каждую строку, передавая вход метода внутри, и позвольте ему выполнить расчет:

DEMO: https://jsfiddle.net/niccord/rk1ec6au/

Основные моменты:

Таблица:

<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()
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...