nmeri17 Ответов: 1

Замените заполнитель значением из объекта JSON


У меня есть элемент DOM с дочерними элементами, которые содержат заполнители. Мне нужно перебрать объект в массиве JSON и заменить заполнители соответствующими ключами в массиве.

Что я уже пробовал:

Вот html-элемент, который я хочу прототипировать:
<pre><div id="foods">
  <div class="food-menu">
    <img src=/{{image}}>
    <p>{{name}}</p>
    <p>{{price}}</p>
  </div>
</div>


Тогда мой JS код выглядит следующим образом:

var prototype = $(".food-menu").eq(0);
            
            data.forEach(function(b) {
      var newFood = prototype.clone().appendTo($("#foods"));

      newFood.html().replace(/(\{\{(\w+)\}\})/gi, function(matches, istMatch) {
        return b[istMatch.toString()];
      });

      data = [{
        "_id": "588b1fcb74e6c500d0d06bf8",
        "type": "cakes",
        "name": "white cake",
        "price": "53.115585580044765",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bf9",
        "type": "cakes",
        "name": "strawberry cake",
        "price": "70.97793026186996",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfa",
        "type": "cakes",
        "name": "cupcakes",
        "price": "49.96683058076812",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfb",
        "type": "cakes",
        "name": "chocolate cake",
        "price": "44.344115951103035",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfc",
        "type": "cakes",
        "name": "berry cake",
        "price": "47.17550216232682",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfd",
        "type": "drinks",
        "name": "whiskey",
        "price": "0.028678076457766544",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfe",
        "type": "drinks",
        "name": "vodka",
        "price": "58.894390375434135",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bff",
        "type": "drinks",
        "name": "juice",
        "price": "77.30969339423659",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c00",
        "type": "drinks",
        "name": "heineken",
        "price": "65.3927295846118",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c01",
        "type": "drinks",
        "name": "coke",
        "price": "2.2636518712426",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c02",
        "type": "snacks",
        "name": "popcorn",
        "price": "64.2930268142774",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c03",
        "type": "snacks",
        "name": "hamburger",
        "price": "48.89626145534767",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c04",
        "type": "snacks",
        "name": "digestive biscuits",
        "price": "93.3497353037074",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c05",
        "type": "snacks",
        "name": "chips",
        "price": "63.459315048229016",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c06",
        "type": "snacks",
        "name": "chin chin",
        "price": "9.608763915240747",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c07",
        "type": "soups",
        "name": "Ogbono",
        "price": "64.40284806037988",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c08",
        "type": "soups",
        "name": "egusi",
        "price": "99.68697142243515",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c09",
        "type": "soups",
        "name": "efo riro",
        "price": "89.32812199871545",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c0a",
        "type": "soups",
        "name": "Edikaikong",
        "price": "29.871174566764623",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c0b",
        "type": "soups",
        "name": "bitter leaf",
        "price": "40.503677589544786",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c0c",
        "type": "soups",
        "name": "afang",
        "price": "36.13059103755023",
        "__v": 0
      }]


Демо скрипка здесь Edit fiddle - JSFiddle[^]
Он просто ничего не заменяет :(

Bryian Tan

код не работает, есть синтаксические ошибки

nmeri17

Я изменил код. Никаких ошибок пока это не заменяет. Новая скрипка https://jsbin.com/nunapo/edit?js, консоль, выход

Richard Deeming

Возможно, вы захотите взглянуть на существующую библиотеку, например Handlebars.js[^], а не пытаться свернуть свой собственный.

Karthik_Mahalingam

возможное решение..

nmeri17

Это всего лишь крошечная функция, которая не требует целой библиотеки. В конце концов я ее разгадал. Проблема была в том, что я ссылался на 1-й матч вместо 2-го. См. обновленную скрипку https://jsbin.com/nunapo/edit?js, выход

Karthik_Mahalingam

Хорошо,
опубликуйте его как решение и закройте этот пост, он может помочь другим в будущем,

nmeri17

Как мне принять свой ответ или закрыть вопрос?

Karthik_Mahalingam

Принять ответ :)

1 Ответов

Рейтинг:
8

nmeri17

Текущая, более надежная функция выглядит следующим образом

function renderConstruct(datas, target, prototype) {
				$(datas).each(function(index, data) {
					var clone = prototype.first().clone(), name = clone.show().unwrap().html().replace(/\{\{(\w+)\}\}/gi, function (match, $1) {
						
						// resetting the value of `username_search` to `username`
						if (data["username"] !== undefined) {
							data["username_search"] = data["username"];
						}

						if (data[$1] != undefined) {
							return data[$1];
						}
							return "";
						});
						target.append($("<li/>").html(name));
				});

				// if the available image is unavailable, serve default
				$.each($("img", target), function(index){
					var that = $(this);

					/* wrapping this in a timeout cuz the instant images are loaded into the dom,
					* they arent fetched from the server immediately, hence their default naturalHeight == 0 so it needs
					* some time before confirming its nonexistence and replacing it with the default
					*/
					setTimeout(function() {
						if (that[0].naturalHeight == 0) {
							that.attr("src", "/images/default.jpg")
						}
					}, 1000);
				})

			}


По просьбе @Картик