我可以呈现动态内容并使用模板引擎 (ejs)

Can i render dynamic content and use a template engine (ejs)

我正在构建天气应用程序作为练习使用 express 和 ejs 的一种方式。 我正在使用 app.get 从 darkSky 的 API 请求信息。 此调用进行一次并且成功,我也可以在我的 index.ejs 文件中呈现它。

我想使用 moment.js 添加一个使用 setInterval 调用的实时时钟功能。 (就是注释掉的函数'updateTime()')

因为我不想在每次时钟更新时回忆天气 API,我认为它需要在 app.get 调用之外。

我不确定如何设置它,因为我似乎无法使用 DOM 操作来添加时钟功能。

有没有办法在我的 ejs 中获取与我的 API 调用分开的动态内容?

(ps - 代码片段不会 运行,我只是想添加代码以供参考)

const path = require('path')
const express = require('express')
const request = require('request')
const moment = require('moment')

const app = express();
const publicDirectoryPath = path.join(__dirname, '/public')

app.use(express.static(publicDirectoryPath))
app.set('view engine', 'ejs');

let sush = 'e20fe780791cad1d4d4d7b8484f970a5';
let lat = 39.892692;
let lng = -86.290568;

let apiUrl = `https://api.darksky.net/forecast/${sush}/${lat},${lng}`;

// function updateTime() {
//     let dayTime = moment().format("dddd h:mma")
//     console.log(dayTime)
//  }
//  setInterval(updateTime, 5000)

// app.use("/", function (req, res){
    let dayTime;
    function updateTime() {
        dayTime = moment().format("dddd h:mma")
        console.log(dayTime)
        return dayTime
     }
     setInterval(updateTime, 5000)
    //  res.render('index.ejs', {dayTime:dayTime})
// })

app.get('/', function (req, res) {

    request(apiUrl, function (error, response, body) {

        if (error){
            console.log('hey, hi, i didnt work - am i internet?')
        } 
        
        weather_json = JSON.parse(body);

        let dataDayThree = weather_json.daily.data[2].time;
        let dataDayFour = weather_json.daily.data[3].time;
        let dataDayFive = weather_json.daily.data[4].time

        let daytwo = moment.unix(weather_json.daily.data[1].time).format("dddd")
        let daythree = moment.unix(dataDayThree).format("dddd")
        let dayfour = moment.unix(dataDayFour).format("dddd")
        let dayfive = moment.unix(dataDayFive).format("dddd")

        let iconCurrentlyOut = weather_json.currently.icon;
        let iconTodayOut = weather_json.daily.data[0].icon;
        let iconTomorrowOut = weather_json.daily.data[1].icon;
        let iconDay3Out = weather_json.daily.data[2].icon;
        let iconDay4Out = weather_json.daily.data[3].icon;
        let iconDay5Out = weather_json.daily.data[4].icon;

        function iconLooper(x){

            switch (x) {
                case 'rain':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--lV_oG1pX--/v1515194565/rainy-6_pzlrlc.svg";
                    break;
                case 'snow':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--EsqjgOhi--/v1515194606/snowy-6_zl9kwx.svg";
                    break;
                case 'clear-day':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s---6vDoixr--/v1515194528/day_shry4k.svg";
                    break;
                case 'clear-night':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--CxSp0zXi--/v1515194530/night_quuh8p.svg";
                    break;
                case 'sleet':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--yeTLFcMd--/v1515194570/rainy-7_sdbkyl.svg";
                    break;
                case 'wind':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg"
                    break;
                case 'fog':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg"
                    break;
                case 'cloudy':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg";
                    break;
                case 'partly-cloudy-day':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--pkzBuC_i--/v1515194500/cloudy-day-1_n3vykl.svg";
                    break;
                case 'snow':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--DdrT7Iph--/v1515194500/cloudy-night-1_ro8fb5.svg";
                    break;
                default:
                    console.log('i dont know whats goin on')    
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg";
                    defaultTest = "i am an unkno"
            }
            return iconCurrently
        }

          ///////////////////////////////////////////////////////////////////////////////////////////////
         // if default in switch is activated add in what the actual weather is, like 'thunderstorms' //
        //////////////////////////////////////////////////////////////////////////////////////////////

        // function updateTime() {
        //     dayTime = moment().format("dddd h:mma")
        //     console.log(dayTime)
        //     return dayTime
        //  }
        //  setInterval(updateTime, 5000)

        let weather = {
            // date & time
            //dayTime: updateTime(),
            date: moment().format("MMM Do. YYYY"),
            // current
            currentTemp: Math.round(weather_json.currently.temperature),
            summary: weather_json.currently.summary,
            currentIcon: iconLooper(iconCurrentlyOut),
            currentFeelLike: Math.round(weather_json.currently.apparentTemperature),
            currentHumidity: Math.round(100 * (weather_json.currently.humidity)),
            dailySummary: weather_json.daily.summary,
            todayHi: Math.round(weather_json.daily.data[0].temperatureMax),
            todayLo: Math.round(weather_json.daily.data[0].temperatureMin),
            todayIcon: iconLooper(iconTodayOut),
            // tomorrow
            dayTwo: daytwo,
            dayTwoHi: Math.round(weather_json.daily.data[1].temperatureMax),
            dayTwoLo: Math.round(weather_json.daily.data[1].temperatureMin),
            dayTwoIcon: iconLooper(iconTomorrowOut),
            // day three
            dayThree: daythree,
            dayThreeHi: Math.round(weather_json.daily.data[2].temperatureMax),
            dayThreeLo: Math.round(weather_json.daily.data[2].temperatureMin),
            dayThreeIcon: iconLooper(iconDay3Out),
            // day four
            dayFour: dayfour,
            dayFourHi: Math.round(weather_json.daily.data[3].temperatureMax),
            dayFourLo: Math.round(weather_json.daily.data[3].temperatureMin),
            dayFourIcon: iconLooper(iconDay4Out),
            // day five
            dayFive: dayfive,
            dayFiveHi: Math.round(weather_json.daily.data[4].temperatureMax),
            dayFiveLo: Math.round(weather_json.daily.data[4].temperatureMin),
            dayFiveIcon: iconLooper(iconDay5Out)
        }

        let weatherData = {
            weather: weather
        }

        res.render('index', weatherData)
    })

});

app.listen(8000);
<!DOCTYPE html>
    <head>
        <title>weatherApp</title>
        <link rel="stylesheet" href="/css/style.css">
    </head>
    <body>
    <div id="container">

    <!-- header 
        <div class="header">
            <button class="refresh-btn" onClick="window.location.reload()">Refresh</button>
        </div>
        -->

        <div class="row">
        <!-- icon -->
            <div class="column iconColumn">        
                <img class="currentWeatherIcon" src='<%=weather.currentIcon%>' />
            </div>

        <!-- descriptions -->
            <div class="column description">
            <button class="refresh-btn" onClick="window.location.reload()">Refresh</button>
                <h5><%=weather.currentTemp%>&deg;F  |  <%=weather.summary%></h5> 
                <h5>Feels like <%=weather.currentFeelLike%>&deg; F | humidity <%=weather.currentHumidity%>%</h5>
            </div>
        </div>

        <h6 class="daySummary"><%=weather.dailySummary%></h6>
    <!-- table -->
            <table>
            <th>Today</th>
            <th><%=weather.dayTwo%></th>
            <th><%=weather.dayThree%></th>
            <th><%=weather.dayFour%></th>
            <th><%=weather.dayFive%></th>
            <tr>
              <td>
                <img src='<%=weather.todayIcon%>' />
                  <div class="hi-lo"><%=weather.todayHi%>&deg;-<%=weather.todayLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayTwoIcon%>' />
                  <div class="hi-lo"><%=weather.dayTwoHi%>&deg;-<%=weather.dayThreeLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayThreeIcon%>' />
                  <div class="hi-lo"><%=weather.dayThreeHi%>&deg;-<%=weather.dayThreeLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayFourIcon%>' />
                  <div class="hi-lo"><%=weather.dayFourHi%>&deg;-<%=weather.dayFourLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayFiveIcon%>' />
                  <div class="hi-lo"><%=weather.dayFiveHi%>&deg;-<%=weather.dayFiveLo%>&deg;</div>
              </td>
        
            </tr>
          </table>
</div>
        <script type="text/javascript" src="app.js"></script>
    </body>
</html>

为了进行 DOM 操作,您必须将 JS 文件包含到 HTML,就像您对 CSS 所做的那样。将你的<head>改成这个

<head>
    <title>weatherApp</title>
    <link rel="stylesheet" href="/css/style.css">
    <script src="/js/script.js">
</head>

css 附近创建 js 目录并在其中创建 script.js 文件,javascript 您添加到那里可以从您的 ejs 模板执行。

使用客户端显示一个简单的时钟javascript,与服务端渲染无关。您可以在 script 标签内的 ejs 文件中简单地 运行 javascript 代码。检查这个简单的例子,你可以在 https://www.w3schools.com/js/:

上找到

 <!DOCTYPE html>
    <html>
    <head>
    
    </head>
    
    <body onload="startTime()">
    <h3> Here is a simple clock.</h3>
    <div id="clock"></div>
    <script>
    function startTime() {
      var today = new Date();
      var h = today.getHours();
      var m = today.getMinutes();
      var s = today.getSeconds();
      m = checkTime(m);
      s = checkTime(s);
      document.getElementById('clock').innerHTML =
      h + ":" + m + ":" + s;
      var t = setTimeout(startTime, 500);
    }
    // add zero in front of numbers < 10
    function checkTime(i) {
      if (i < 10) {i = "0" + i};  
      return i;
    }
    </script>
    </body>
    </html>