简体   繁体   中英

How to toggle ViewComponent in ASP.NET Core 3.1

I have a View that uses two ViewComponents. One is rendered when the page loads through an ajax call, the other is loaded on a click event. Currently the anchor tag that renders the second ViewComponent just renders it and stays there. I would like to change the behavior so that the anchor tag text changes to "Hide Forecast" and hides the forecast component on click.

I've tried using ViewData to accomplish this but am getting tripped up, I think because I am passing ViewData to the actions that render the ViewComponent, and then the ViewData is not accessible to the main view? Is there any way I can accomplish this with the way my code is currently set up?

View

@model OpenWeather.Models.CityViewModel

@{
    ViewData["Title"] = Model.Name;
}

<!--First ViewComponent, rendered with ajax on load-->
<div id="current-weather">
</div>

<a id="forecast-link" asp-action="Forecast" asp-route-lon="@(Model.Coord.lon)" asp-route-lat="@(Model.Coord.lat)">Get Five-Day Forecast</a>

<!--Second ViewComponent, rendered on above anchor tag click-->
<div id="forecast">
</div>

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
    $(document).ready(function (e) {

        var params = window.location.pathname.split("/")

        $("#current-weather").load("/Home/CurrentWeather?id=" + params[3]);

        $("#forecast-link").click(function (e) {
            e.preventDefault();
            var params = window.location.pathname.split("/");
            $("#forecast").load($(this).attr('href'));
            $(this).hide();
        });

    });
</script>

Controller Actions

        public IActionResult City(double id)
        {
            var city = _openWeatherService.GetCity(id);
            return View("City", new CityViewModel(city));
        }

        public IActionResult CurrentWeather(double id)
        {
            return ViewComponent("CurrentWeather", new { id = id });
        }

        public IActionResult Forecast(double lat, double lon)
        {
            return ViewComponent("Forecast", new { lat = lat, lon = lon });
        }

CurrentWeather View Component

@model OpenWeather.Models.CurrentWeatherViewModel

<h3>@Html.DisplayFor(model => model.Time)</h3>

<div id="current-weather-summary">

    <div id="current-weather-summary-panel-one">
        <h3>@Html.DisplayFor(model => model.Temp)&#x00b0</h3>
        <img src="http://openweathermap.org/img/w/@(Model.Icon).png" />
        <h5>@Html.DisplayFor(model => model.Description)</h5>
    </div>

    <div id="current-weather-summary-panel-two">
        <dl>
            <dt>@Html.DisplayNameFor(model => model.High)</dt>
            <dd>@Html.DisplayFor(model => model.High)&#x00b0</dd>

            <dt>@Html.DisplayNameFor(model => model.Low)</dt>
            <dd>@Html.DisplayFor(model => model.Low)&#x00b0</dd>

            <dt>@Html.DisplayNameFor(model => model.Sunrise)</dt>
            <dd>@Html.DisplayFor(model => model.Sunrise)</dd>

            <dt>@Html.DisplayNameFor(model => model.Sunset)</dt>
            <dd>@Html.DisplayFor(model => model.Sunset)</dd>
        </dl>
    </div>

</div>

Forecast View Component

@model OpenWeather.Models.ForecastViewModel

@{
    foreach (var x in Model.ForecastDays.AsEnumerable())
    {
        <div class="forecast-day">
            <h5>@x.Time</h5>
            <p>@x.Description.</p>
            <img src="http://openweathermap.org/img/w/@(x.Icon).png" />
            <p>Day: @x.TempDay&#x00b0 | Night: @x.TempNight&#x00b0</p>
        </div>
    }
}

Well I wound up using jQuery to accomplish what I wanted. It feels a bit sloppy so and I'd like to accomplish this server-side somehow, so I am open to better suggestions.

$("#forecast-link").click(function (e) {
            e.preventDefault();

            if ($(this).text().indexOf("Get Five-Day Forecast") !== -1) {
                $("#forecast").load($(this).attr('href'));
                $(this).text("Hide Forecast");
            }

            else {
                $("#forecast").empty();
                $(this).text("Get Five-Day Forecast");
            }
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM