无法追加对象

时间:2015-07-31 19:03:37

标签: jquery

我正在尝试创建一个简单的演示,根据给定邮政编码的输入检索电影院放映时间。影院列表嵌套在电影对象的对象中,所以我在每个解析JSON的循环中运行for循环。我也使用timeConvert函数将时间戳转换为美国12小时的时间。

目前,它看起来像这样:

 for (var j=0; j<movie.showtimes.length; j++) {
           listing += '<li class="times-and-places">
                   <div class="movie-theater">' 
                   + movie.showtimes[j].theatre.name
                   + '</div><div class="movie-time"><li>' 
                   + timeConvert(movie.showtimes[j].dateTime.slice(11,16)) 
                   + '</li></div></li>';
        }

这样可以正常工作,但它会为每个电影院放映一个不同的项目,其中包含电影院,看起来有点笨拙。我正在使用的API并没有组合影院的放映时间,每个播放时间都有不同的条目。我基本上是在HTML中复制它。因此,如果一部电影播放了很多次,它将显示:

  

MoviePlace1 1:30 PM MoviePlace1 1:45 PM MoviePlace1 2:00 PM

我希望能够将放映时间结合起来阅读:

  

MoviePlace1 1:30 PM 1:45 PM 2:00 PM

电影API为每个电影院分配一个ID,所以我尝试在for循环中写一个if-else条件。

 for (var j=0; j<movie.showtimes.length; j++) {
          tList.push(movie.showtimes[j].theatre.id);
          var thingToFind = $(this).prev().find('.movie-time');
           var mTime = movie.showtimes[j].dateTime.slice(11,16);
          var mTimeConverted = timeConvert(mTime).toString();

          if (tList[j] != tList[(j-1)] || tList[(j-1)] === null ) {
                    listing += '<li class="times-and-places">
                   <div class="movie-theater">' 
                   + movie.showtimes[j].theatre.name
                   + '</div><div class="movie-time"><li>' 
                   + timeConvert(movie.showtimes[j].dateTime.slice(11,16)) 
                   + '</li></div></li>';

        } else {
          console.log(mTimeConverted);
          listing += thingToFind.append($("li").append(mTimeConverted + '</li>'));

        }

if语句运行正常,检查当前电影院ID是否与前一个相比是唯一的 - 或者前一个ID是否不存在(我在推出电影放映时间后推送ID值的数组清除)环)。

else语句 - 用于组合不同的放映时间 - 将一堆空白jQuery对象附加到上一个列表中:

  

MoviePlace1 4:30 PM [object Object] [object Object]

我已经尝试修改了一百万种不同的方法来返回实际值而不是空白的jQuery对象,但我似乎无法弄明白。有人可以帮忙吗?

这是一个示例电影对象,包括放映时间。

{
    "tmsId": "MV007117430000",
    "rootId": "11455160",
    "subType": "Feature Film",
    "title": "Me and Earl and the Dying Girl",
    "releaseYear": 2015,
    "releaseDate": "2015-01-25",
    "titleLang": "en",
    "descriptionLang": "en",
    "entityType": "Movie",
    "genres": [
        "Comedy drama"
    ],
    "longDescription": "An awkward high-school senior (Thomas Mann) and a gravely ill classmate (Olivia Cooke) surprise themselves by becoming inseparable friends.",
    "shortDescription": "A shy, awkward teenager and a gravely ill classmate become inseparable friends.",
    "topCast": [
        "Thomas Mann",
        "Olivia Cooke",
        "Ronald Cyler II"
    ],
    "directors": [
        "Alfonso Gomez-Rejon"
    ],
    "officialUrl": "http://meandearlmovie.com/",
    "qualityRating": {
        "ratingsBody": "TMS",
        "value": "3.5"
    },
    "ratings": [
        {
            "body": "Motion Picture Association of America",
            "code": "PG-13"
        }
    ],
    "advisories": [
        "Adult Language",
        "Adult Situations"
    ],
    "runTime": "PT01H45M",
    "preferredImage": {
        "width": "240",
        "height": "360",
        "caption": {
            "content": "Me and Earl and the Dying Girl (2015)",
            "lang": "en"
        },
        "uri": "assets/p11455160_p_v5_aa.jpg",
        "category": "Poster Art",
        "text": "yes",
        "primary": "true"
    },
    "showtimes": [
        {
            "theatre": {
                "id": "10420",
                "name": "Violet Crown Cinema"
            },
            "dateTime": "2015-07-21T11:00",
            "barg": false
        },
        {
            "theatre": {
                "id": "10420",
                "name": "Violet Crown Cinema"
            },
            "dateTime": "2015-07-21T17:10",
            "barg": false
        },
        {
            "theatre": {
                "id": "10420",
                "name": "Violet Crown Cinema"
            },
            "dateTime": "2015-07-21T22:10",
            "barg": false
        },
        {
            "theatre": {
                "id": "10984",
                "name": "Alamo Drafthouse South Lamar"
            },
            "dateTime": "2015-07-21T14:15",
            "barg": false
        },
        {
            "theatre": {
                "id": "10984",
                "name": "Alamo Drafthouse South Lamar"
            },
            "dateTime": "2015-07-21T17:05",
            "barg": false
        },
        {
            "theatre": {
                "id": "10984",
                "name": "Alamo Drafthouse South Lamar"
            },
            "dateTime": "2015-07-21T19:50",
            "barg": false
        },
        {
            "theatre": {
                "id": "10984",
                "name": "Alamo Drafthouse South Lamar"
            },
            "dateTime": "2015-07-21T22:10",
            "barg": false
        }
    ]

}

3 个答案:

答案 0 :(得分:1)

Given your input data, you best approach might be to reorganize it like so:

var shows = showtimes.reduce(function (p, c) {
    if (!p[c.theatre.id]) {
        p[c.theatre.id] = {
            theatreName: c.theatre.name,
            showtimes: [c.dateTime]
        };
    } else {
        p[c.theatre.id].showtimes.push(c.dateTime);
    }
    return p;
}, {});

This would give you an object that looked something like this:

{
    "9489": {
        "theatreName": "Alamo Drafthouse at the Ritz",
        "showtimes": [
            "2015-07-21T16:30",
            "2015-07-21T19:30",
            "2015-07-21T22:30"
        ]
    },
    "10420": {
        "theatreName": "Violet Crown Cinema",
        "showtimes": [
            "2015-07-21T12:00",
            "2015-07-21T13:20",
            "2015-07-21T15:50",
            "2015-07-21T18:25"
        ]
    }
}

Now you can iterate through this object (or convert it back to an array if you really want to) with a for...in loop and construct your HTML from it.

Something like:

for (var t in shows) {
    if (shows.hasOwnProperty(t)) {         
        listing += '<li class="times-and-places">'
               + '<div class="movie-theater">' 
               + shows[t].theatreName
               + '</div><div class="movie-time">'; 
        for (var i=0; i < shows[t].showtimes.length; i++) {
            listing += '<li>' 
               + timeConvert(shows[t].showtimes[i].slice(11,16)) 
               + '</li>';
        }

        listing += '</div></li>';
    }
}

Which would give HTML that eventually looked something like this (ignoring whatever timeConvert might do):

<li class="times-and-places">
    <div class="movie-theater">Alamo Drafthouse at the Ritz</div>
    <div class="movie-time">
        <li>16:30</li>
        <li>19:30</li>
        <li>22:30</li>
    </div>
</li>
<li class="times-and-places">
    <div class="movie-theater">Violet Crown Cinema</div>
    <div class="movie-time">
        <li>12:00</li>
        <li>13:20</li>
        <li>15:50</li>
        <li>18:25</li>
    </div>
</li>

答案 1 :(得分:0)

变化:

listing += thingToFind.append($("li").append(mTimeConverted + '</li>'));

为:

listing += '<li>' + mTimeConverted + '</li>';

循环完成后,执行:

thingToFind.append(listing);

答案 2 :(得分:0)

You could reduce the showtimes array:

var showtimes = [{
  "theatre": {
    "id": "10420",
    "name": "Violet Crown Cinema"
  },
  "dateTime": "2015-07-21T11:00",
  "barg": false
}, {
  "theatre": {
    "id": "10420",
    "name": "Violet Crown Cinema"
  },
  "dateTime": "2015-07-21T17:10",
  "barg": false
}, {
  "theatre": {
    "id": "10420",
    "name": "Violet Crown Cinema"
  },
  "dateTime": "2015-07-21T22:10",
  "barg": false
}, {
  "theatre": {
    "id": "10984",
    "name": "Alamo Drafthouse South Lamar"
  },
  "dateTime": "2015-07-21T14:15",
  "barg": false
}, {
  "theatre": {
    "id": "10984",
    "name": "Alamo Drafthouse South Lamar"
  },
  "dateTime": "2015-07-21T17:05",
  "barg": false
}, {
  "theatre": {
    "id": "10984",
    "name": "Alamo Drafthouse South Lamar"
  },
  "dateTime": "2015-07-21T19:50",
  "barg": false
}, {
  "theatre": {
    "id": "10984",
    "name": "Alamo Drafthouse South Lamar"
  },
  "dateTime": "2015-07-21T22:10",
  "barg": false
}];

function reduceShowtimes(showtimes) {
  var theatres = {}
  var showsReduced = showtimes.reduce(function(arr, obj) {
    var theatreName = obj.theatre.name;
    if (theatres[theatreName] !== undefined) {
      var theatreIndex = theatres[theatreName];
      var theatreObj = arr[theatreIndex];
      theatreObj.dateTime.push(obj.dateTime);
    } else {
      theatres[theatreName] = arr.length;
      obj.dateTime = [obj.dateTime];
      arr.push(obj);
    }
    return arr;
  }, []);
  return showsReduced;
}
var result = document.getElementById('result').innerHTML = JSON.stringify(reduceShowtimes(showtimes), null, '\t');
<pre id="result"></pre>