Ajax로 호출된 데이터로 동적 지도 표현시 지도깨짐 현상

안녕하세요 부동산 관련 사이트 개발하면서 다음지도 API 호출하면서 잘 사용중인데요
문의 내용 찾아보다가 막혀서 여쭤봅니다

function makeTradingCompare(jdataList){
		var htmlStr = "";
		var index = 0;
		
		$(jdataList).each(function(){
			htmlStr += "<div style='display: inline-block; width: 45%;'>";
			htmlStr += "<div class='table_wrap'>";
			htmlStr += "<table class='w_table w_table_center'>";
			htmlStr += "<colgroup>";
			htmlStr += "<col width='150px'>";
			htmlStr += "<col width='*'>";
			htmlStr += "</colgroup>";
			htmlStr += "<tr style='cursor:pointer;'>";
			htmlStr += "<td>"+this.bldgNm+"</td>";
			htmlStr += "<td>"+this.roadNmAddr+"</td>";
			htmlStr += "</tr>";
			htmlStr += "<td colspan='2'><div id='kakaoMap"+index+"' style='width:100%;height:350px;'></div></td>";
			htmlStr += "<tr>";
			htmlStr += "</tr>";
			htmlStr += "</table>";
			htmlStr += "</div>";
			htmlStr += "</div>";
			
			$("#list_compare").html(htmlStr);
			
			//compareKakaoMap(this.roadNmAddr, this.bldgNm, index); //카카오맵 호출
			
			//console.log("** "+this.bldgNm);
			//console.log("** "+this.roadNmAddr);
			//console.log("** "+index);
			
			index++;
		});
		console.log(htmlStr);
		$("#list_compare").html(htmlStr);
		
		index = 0;
		$(jdataList).each(function(){
			
			compareKakaoMap(this.roadNmAddr, this.bldgNm, index); //카카오맵 호출
			index++;
		});
	}

function compareKakaoMap(roadNmAddr, bldgNm, index){
		console.log(roadNmAddr, bldgNm, index);
		var addr = bldgNm;
		
		var mapContainer = document.getElementById("kakaoMap"+index), // 지도를 표시할 div 
	    mapOption = { 
	        center: new kakao.maps.LatLng(33.517954, 126.5213165), // 지도의 중심좌표
	        level: 4 // 지도의 확대 레벨
	    };
	    // 지도를 표시할 div와  지도 옵션으로  지도를 생성합니다
		var map = new kakao.maps.Map(mapContainer, mapOption);
		//map.relayout();
		// 주소-좌표 변환 객체를 생성합니다
		var geocoder = new kakao.maps.services.Geocoder();
		// 주소-좌표 담기
		var coords = new kakao.maps.LatLng(33.517954, 126.5213165);
	  	
		if(bldgNm == null || bldgNm == "")
		{
			addr = roadNmAddr;
		}
		
		geocoder.addressSearch(roadNmAddr, function(result, status) {
		//console.log(4);
			// 정상적으로 검색이 완료됐으면
			if (status === kakao.maps.services.Status.OK) {
				
		        coords = new kakao.maps.LatLng(result[0].y, result[0].x);
		
		        // 결과값으로 받은 위치를 마커로 표시합니다
		        var marker = new kakao.maps.Marker({
		            map: map,
		            position: coords
		        });
		
		        // 인포윈도우로 장소에 대한 설명을 표시합니다
		        var infowindow = new kakao.maps.InfoWindow({
		            content: '<div style="width:150px;text-align:center;padding:5px;font-size:12px;">'+addr+'</div>'
		        });
		        infowindow.open(map, marker);
		    } 
		    
		});  // end addressSearch
		
		// 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
		map.setCenter(coords);
        
        // 마우스 드래그로 지도 이동 막기
		//map.setDraggable(false);
		
		// 마우스 휠로 지도 확대,축소 막기
	 	//map.setZoomable(false); 
	}.

위와 같은 코드 형식으로 호출을 하면 지도는 표현 되는데 깨져서 나오는게
동적으로 가져와서 깨지는게 아닌가 싶더라구요

동적으로 가져올때 뭘 더 추가해야하는건지ㅠ

일단 맵이 끝에 하나만 나오는건 해결했고 깨짐 현상만 해결이 안되서 여쭤봅니다

캡처

탭으로 지도를 표시할 경우 각 탭이 보여지는 시점에 map.relayout();을 호출해야 합니다.
아래 답변 참고해주세요.

1개의 좋아요

넵 안녕하세요 답변주셔서 감사합니다… 위에 방법을 찾아서 안해본건 아니지만 동적으로 코드를 생성에서 불러오질 못한게 맞는것 같습니다… 코드를 공유해드릴테니 한번 봐주시면 감사하겠습니다

		 var map1 = compareKakaoMap(this.roadNmAddr, this.bldgNm, index); //카카오맵 호출
			relayout(map1);

//맵호출생략
geocoder0.addressSearch(roadNmAddr, function(result, status) {
// 정상적으로 검색이 완료됐으면
if (status === kakao.maps.services.Status.OK) {
console.log(1);
//console.log("*** “+timeoutId);
coords0 = new kakao.maps.LatLng(result[0].y, result[0].x);
//console.log(result[0].y+”,"+ result[0].x);
// 결과값으로 받은 위치를 마커로 표시합니다
var marker0 = new kakao.maps.Marker({
map: map0,
position: coords0
});

		        // 인포윈도우로 장소에 대한 설명을 표시합니다
		        var infowindow0 = new kakao.maps.InfoWindow({
		            content: '<div style="width:150px;text-align:center;padding:5px;font-size:12px;">'+addr+'</div>'
		        });
		        
		        infowindow0.open(map0, marker0);
		    	console.log(2);
		        map0.setCenter(coords0);
		    } 
		    
		});  // end addressSearch
		
			// 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
			
			
			//console.log(3);
			//map0.relayout();
		//	}, 50); 
	        // 마우스 드래그로 지도 이동 막기
			//map.setDraggable(false);
			
			// 마우스 휠로 지도 확대,축소 막기
		 	//map.setZoomable(false); 
		//}
		return map0;
	}
	
	function relayout(map) {    

	    // 지도를 표시하는 div 크기를 변경한 이후 지도가 정상적으로 표출되지 않을 수도 있습니다
	    // 크기를 변경한 이후에는 반드시  map.relayout 함수를 호출해야 합니다 
	    // window의 resize 이벤트에 의한 크기변경은 map.relayout 함수가 자동으로 호출됩니다
	    console.log(3);
	    map.relayout();
	}`  // 로그를 보니 3부터 나오더라구요 속도가 빨라서 안되는것 같은데.. 헷갈리네요 ㅠㅠ

먼저 지도가 깨지는 현상은
주소 리스트를 반복문으로 실행하면서
각 탭에 맞는 지도 객체를 생성할 때 이를 관리하는 변수가 필요합니다.
그래서 탭을 클릭할 때 탭에 맞는 지도 객체를 가져와 relayout을 해야 지도가 깨지지 않습니다.

그리고 비동기로 주소를 처리할 땐 순서가 보장되지 않으므로
순차대로 처리할 수 있도록 async-await 방식을 사용해주면 됩니다.
아래 로직 참고해서 수정해주세요.

let maps = [];
let position = [];
const addressList = ["제주특별자치도 제주시 첨단로 242", "경기도 성남시 분당구 판교역로 235","경기도 성남시 분당구 판교역로 231","제주특별자치도 서귀포시 상효동 산 1-2"];
const geocoder = new kakao.maps.services.Geocoder();
const addressSearch = address => {
    return new Promise((resolve, reject) => {
        geocoder.addressSearch(address, function(result, status) {
            if (status === kakao.maps.services.Status.OK) {
                resolve({result});
            } else {
                reject(status);
            }
        });
    });
};

(async () => {
    try{
        for(const [i,addr] of addressList.entries()) {
            const mapContainer = document.getElementById('map'+i), // 지도를 표시할 div
            mapOption = {
                center: new kakao.maps.LatLng(37.566826, 126.9786567), // 지도의 중심좌표
                level: 3 // 지도의 확대 레벨
            };

            // 지도를 생성합니다
            const map = new kakao.maps.Map(mapContainer, mapOption);

            const data = await addressSearch(addr);
            coords = new kakao.maps.LatLng(data.result[0].y, data.result[0].x);
            // 결과값으로 받은 위치를 마커로 표시합니다
            var marker = new kakao.maps.Marker({
                map: map,
                position: coords
            });

            // 인포윈도우로 장소에 대한 설명을 표시합니다
            var infowindow = new kakao.maps.InfoWindow({
                position: coords,
                content: '<div style="width:150px;text-align:center;padding:5px;font-size:12px;">'+addr+'</div>'
            });

            infowindow.open(map, marker);
            map.setCenter(coords);

            //주소 좌표와 생성한 지도 객체를 배열에 담아줍니다.
            position.push(coords);
            maps.push(map);
        }
    } catch(e) {
        console.error(e);
    }
})();

//TODO: 탭 클릭 이벤트에서 i 번째 지도 가져와서 relayout해주세요.
// const map = maps[idx];
// map.relayout();
// map.setCenter(position[idx]);
1개의 좋아요

감사합니다 ~ 덕분에 잘 해결됐습니다 ^^ 새로운방법을 알게되서 넘 좋네요:heart_eyes:

1개의 좋아요