【问题标题】:Object with very strange behavior inside component组件内部行为非常奇怪的对象
【发布时间】:2022-01-02 16:49:52
【问题描述】:

我有一个行为非常奇怪的对象。不知道怎么回事。

我的代码:

<script>
    import { page } from '$app/stores'
    const { listingId } = $page.params
    import { db } from '../../../../firebase.config'
    import { goto } from '$app/navigation'
    import { getDoc, doc } from 'firebase/firestore'
    import { getAuth } from 'firebase/auth'
    import { scale } from 'svelte/transition'
    import LeafletMap from '$lib/LeafletMap.svelte'

    let listing = {}
    
    const auth = getAuth()

    const fetchListing = async () => {
        const docRef = doc(db, 'listings', listingId)
        const docSnap = await getDoc(docRef)

        if (docSnap.exists) {
            listing = docSnap.data()
        }

        console.log('listing', listing)
    }
    fetchListing()

    // call listing
    listing
</script>

<main in:scale>
    
    <div class="listingDetails">
        <p class="listingName">
            {listing.name} - ${listing.offer ? listing.discountedPrice : listing.regularPrice}
        </p>
        <p class="listingLocation">
            {listing.location}
        </p>
        <p class="listingType">
            Para {listing.type === 'rent' ? 'Alugar' : 'Vender'}
        </p>
        {#if listing.offer}
            <p class="discoutPrice">
                ${listing.regularPrice - listing.discountedPrice}
                de desconto
            </p>
        {/if}
        <ul class="listingDetailsList">
            <li>
                {#if listing.bedrooms > 1}
                    {listing.bedrooms} quartos
                {/if}
                {#if listing.bedrooms === 1}
                    {listing.bedrooms} quarto
                {/if}
            </li>
            <li>
                {#if listing.bathrooms > 1}
                    {listing.bathrooms} banheiros
                {/if}
                {#if listing.bathrooms === 1}
                    {listing.bathrooms} banheiro
                {/if}
            </li>
            <li>
                {#if listing.parking == true}
                    estacionamento
                {:else}
                    sem estacionamento
                {/if}
            </li>
            <li>
                {#if listing.furnished == true}
                    mobiliado
                {:else}
                    não mobiliado
                {/if}
            </li>
        </ul>
        <p class="listingLocationTitle">Localização</p>

        <LeafletMap lat={'26.2137376'} lng={'-80.2094237'} zoom={15} />

        {#if auth.currentUser?.uid == listing.user}
            <a href={`/contact/${listing.user}?listingName=${listing.name}`} class="primaryButton">
                Entre em contato com o proprietário
            </a>
        {/if}
    </div>
</main>

我的console.log('listing', listing)在函数fetchListing里面调用列表:

但是如果我尝试做同样的事情,在函数之外我会得到这个:

这很有趣,因为有效,但我需要访问组件 &lt;LeafletMap/&gt; 内的 listing.geolocation.latlisting.geolocation.lng。如果我把这个{listing.geolocation.lat.toString()} 放在组件之外,我会得到这个数字。但如果我这样做:

<LeafletMap lat={listing.geolocation.lat.toString()} lng={'-80.2094237'} zoom={15} />

我知道了error: TypeError: Cannot read properties of undefined (reading 'lat')

我的&lt;LeafletMap/&gt; 组件:

<script>
    import { onMount } from 'svelte'
    import { browser } from '$app/env'
    export let lat
    export let lng

    onMount(async () => {
        if (browser) {
            const leaflet = await import('leaflet')

            const map = leaflet.map('map').setView([lat, lng], 13)

            leaflet
                .tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    attribution:
                        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                })
                .addTo(map)

            leaflet.marker([lat, lng]).addTo(map)
        }
    })
</script>

<main>
    <div id="map" />
</main>

<style>
    @import 'https://unpkg.com/leaflet@1.7.1/dist/leaflet.css';
    main #map {
        height: 800px;
    }
</style>

如果我这样做:&lt;LeafletMap lat={'42.233283'} lng={'-80.2094237'} zoom={15} /&gt; 我得到了完美的位置,所以我的组件正在工作。

【问题讨论】:

    标签: svelte sveltekit


    【解决方案1】:

    fetchListing 是一个异步函数,因此在呈现LeafletMap 时可能不会设置listing

    我的建议是在设置纬度和经度后添加/更新标记,如下例所示。这还允许您在运行时更新标记,并且可以轻松扩展多个标记。

    <script>    
        export let lat;
        export let lng;
    
        let map;
        let mounted = false;
        $: if (mounted && lat && lng) updateMarkers(lat, lng);
    
        async function updateMarkers(latitude, longitude) {      
          const leaflet = await import('leaflet');
          leaflet.marker([latitude, longitude]).addTo(map);
          map.setView([latitude, longitude], 13);
        }
    
        async function createMap(container) {
          const leaflet = await import('leaflet');
          map = leaflet.map(container);
          leaflet
            .tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
              attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            })
            .addTo(map);
          return map;
        }
    
        function mapAction(container) {
          createMap(container).then(function(map){
            mounted = true;
            return {
              destroy: () => {
                map.remove();
              }
            };
          });          
        }
    </script>
    
    <div style={$$props.style} use:mapAction />
    
    <style>
      @import 'https://unpkg.com/leaflet@1.7.1/dist/leaflet.css';
      div {
          height: 800px;
      }
    </style>
    

    【讨论】:

    • 非常感谢,米温!完美运行。 :)
    猜你喜欢
    • 1970-01-01
    • 2012-11-09
    • 2016-03-13
    • 2011-03-01
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多