将Razor变量传递给JavaScript函数

3

我正在开发一个基于Asp.net MVC的拍卖网站,我想要显示每个物品拍卖还剩下多少时间。我通过模型将物品列表传递到cshtml页面上,然后像这样遍历它们:

我的JavaScript函数以启动计时器:

function countdown(time) {
    // Get todays date and time
    var now = new Date().getTime();

    // Find the distance between now an the count down date
    var distance = time - now;

    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    // Display the result in the element with id="timeLeft"
    document.getElementById("timeLeft").innerHTML = days + "d " + hours + "h "
        + minutes + "m " + seconds + "s ";

}, 1000);

然后我的模型迭代器,使用项目的结束日期调用js函数

@foreach (var item in Model)
    {
        //code here
        countdown(@item.EndDate)
        <text id="timeLeft"></text>
    }

我有一个脚本被引用:<script src="~/Scripts/countdown.js" /> 问题是如何使用C# Razor变量调用这个JS函数。对于一个项目的基本操作,我遇到了问题:
<body onload= "countdown('@item.EndDate')">

当我放置我的剃须刀变量时,它会使我的函数变灰。我需要如何将我的变量传递到我的js函数中?
例如:(使用单个模型项)
{{link1:enter image description here}} {{link2:enter image description here}}
4个回答

3

试试使用这个语法:

@foreach (var item in Model)
{
    //code here
    countdown(`${@item.EndDate}`)
}

似乎我不能直接将该调用放入我的for循环中,当我尝试使用单个项目进行<body onload= "countdown(`${@item.EndDate}`)">时,我遇到了相同的问题,即vs无法识别该函数。 - C.Math
这实际上是我第一次尝试的,也在我的帖子中提到了,但仍然不起作用:( - C.Math
语法很好。我建议调试您的视图并查看该变量的值。 - dotnetdev4president
请查看更新后带有图片的帖子,我也相信语法是正确的。 - C.Math
在.NET 5中,我尝试过不加 { },它对我起作用了。 - gl3yn
显示剩余3条评论

2
如果你想在javascript中创建一个计时器,我会使用window.setInterval函数,然后将第二个参数设置为时间间隔。
这个countdown函数需要传递三个参数:
  1. 结束年份
  2. 结束月份
  3. 结束日期

    function countdown(endYear,endMonth,endDay) {
      window.setInterval(function () { StartCount(endYear, endMonth, endDay, 'andy timer'); }, 1000);
    }

    function StartCount(endYear,endMonth,endDay){
     var now=new Date();
     var endDate=new Date(endYear,endMonth-1,endDay);

     var leftTime=endDate.getTime() - now.getTime();

     var leftSecond=parseInt(leftTime/1000);

     var day=Math.floor(leftSecond/(60*60*24));

     var hour=Math.floor((leftSecond-day*24*60*60)/3600);

     var minute=Math.floor((leftSecond - day * 24 * 60 * 60 - hour * 3600) / 60);

     var second = Math.floor(leftSecond - day * 24 * 60 * 60 - hour * 3600 - minute * 60);
     
          document.getElementById("timeLeft").innerHTML = day + "d " + hour + "h "
        + minute + "m " + second + "s ";
    }

    countdown(2018,10,5)
<div id='timeLeft'></div>

您可以在 body 标签上使用这个。
<body onload= "countdown(@Model.EndDate.Year,@Model.EndDate.Month,@Model.EndDate.Day)">

编辑

这个在c# MVC在线上可以运行:https://dotnetfiddle.net/ERcwAb


不幸的是,我的问题仍然存在,因为当我尝试调用带有双引号的<body onload=">并且我有一个带有“@”符号的参数时,它会将函数变成字符串,并且无法识别调用它。 - C.Math
我仍然有如图片所示的同样问题。变量完全没问题,而是函数变得无法识别。 - C.Math
除非我漏掉了什么,否则看起来你发布的演示应用程序链接并没有保存你所做的更改。 - C.Math
我使用你的脚本并在脚本底部调用countdown(Model.EndDate.Year, Model.EndDate.Month, Model.EndDate.Day,Model.EndDate.Hour)成功地为一个项目使其工作(当然要加上@)。虽然我仍无法使用body onload,但对于单个项目来说这已经足够了。 - C.Math
如果您想设置多个项目,则需要创建它们的div并将此函数附加到它们。 - D-Shih
我发布了一个解决多个项目的答案,现在只需要让它随页面一起加载,这可能与修复<body onload>有关? - C.Math

0

我想出了一个疯狂的方法来实现我想做的事情,可能不是很高效,可能会对整个编程社区构成罪恶,但是这就是它:

@foreach (var item in Model)
{
    <script>
    function countdown(endYear, endMonth, endDay, endHours, endMin, num) {
        window.setInterval(function () { StartCount(endYear, endMonth, endDay, endHours, endMin, num); }, 1000);
    }

    function StartCount(endYear, endMonth, endDay, endHours, endMin, num) {
        var now = new Date();
        var endDate = new Date(endYear, endMonth - 1, endDay, endHours, endMin);

        var leftTime = endDate.getTime() - now.getTime();

        var leftSecond = parseInt(leftTime / 1000);

        var day = Math.floor(leftSecond / (60 * 60 * 24));

        var hour = Math.floor((leftSecond - day * 24 * 60 * 60) / 3600);

        var minute = Math.floor((leftSecond - day * 24 * 60 * 60 - hour * 3600) / 60);

        var second = Math.floor(leftSecond - day * 24 * 60 * 60 - hour * 3600 - minute * 60);

        var id = "timeLeft" + num;

        document.getElementById(id).innerHTML = day + "d " + hour + "h "
      + minute + "m " + second + "s ";
    }
    countdown(@item.EndDate.Year, @item.EndDate.Month, @item.EndDate.Day,@item.EndDate.Hour, @item.EndDate.Minute, @num)
    </script>

    @{string countNum = "timeLeft" + num;}
     <text id= @countNum></text>
     @{num++;}
     //code
}

但它仍然异步加载,其中所有项目都会加载,然后时钟会晚一秒钟出现,所有内容都会相应地移动。这可能是由于我最初无法调用body onload的问题。


0

这是我如何在 Asp Net MVC 5 中将变量customFields传递给我的按钮onAddRow()

    <form id="contactsForm">
        <table>
            [...]
        </table>
        <button type="button">Save To Excel</button>
        @{
            <button type="button" onclick="onAddRow(`@customFields`);">Add Row</button>
        }
    </form>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接