Partial View not refreshing

18,384

I think it is because all partial views are cached by default, what I would do is to create a method in the controller to return an ActionResult like so, with the output cache attribute of 0, so it does not cache

[OutputCache(Duration = 0)]
public ActionResult ImageGalleryAction()
{
  // do return your cshtml name here
  return PartialView("ImageGallery");
}

I would give an id to your imageGalleryDiv, change your reloadGallery method to load the partial view on onload event as well and remove the @Html.Partial like so

<script>
function reloadGallery(){
   $('#myImageGallery').load("ImageGalleryAction");
}
</script>

<div id="myImageGallery" class="ImageGallery" onload="reloadGallery()">
 </div>

That way, your partial view will be manually injected/refreshed via jquery and it won't be cached.

Cheers

Share:
18,384
JMon
Author by

JMon

Updated on June 16, 2022

Comments

  • JMon
    JMon almost 2 years

    I have a partial view on a cshtml page as follows :-

    @model MvcCommons.ViewModels.CompositeViewModel
    
    @{
    ViewBag.Title = "Edit";
    }
    
    @using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
        <fieldset>
        <legend>Article</legend>
    
        @Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID)
    
        <div class="editor-label">
            @Html.LabelFor(model => model.ArticleViewModel.Article.CategoryID, "Category")
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.ArticleViewModel.Article.CategoryID, (SelectList)ViewBag.CategoryID) 
            @Html.ValidationMessageFor(model => model.ArticleViewModel.Article.CategoryID)
        </div>
    
        <div class="editor-label">
            @Html.LabelFor(model => model.ArticleViewModel.Article.ArticleTitle)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ArticleViewModel.Article.ArticleTitle)
            @Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleTitle)
        </div>
    
        <div class="editor-label">
            @Html.LabelFor(model => model.ArticleViewModel.Article.ArticleDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ArticleViewModel.Article.ArticleDate)
            @Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleDate)
        </div>
    
            @Html.HiddenFor(model => model.PageViewModel.Page.PageTitle, new { id = "PageTitle" })
            @Html.HiddenFor(model => model.PageViewModel.Page.PageAction, new { id = "PageAction" })
            @Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID, new { id = "ArticleID" })
        <div class="ImageGallery">
            @Html.Partial("~/Views/Shared/ImageGallery.cshtml", Model)
        </div>
    
    </fieldset>
      }
    
    <div>
    @Html.ActionLink("Back to List", "Index")
    

    The ImageGallery.cshtml Partial View is as follows :-

    @model MvcCommons.ViewModels.CompositeViewModel
    
    @{
    ViewBag.Title = "Modal image uploader";
    }
    
    
    <script type="text/javascript">
    var pageTitle = $('#PageTitle').val();
    var pageAction = $('#PageAction').val();
    var id = $('#ArticleID').val();
    
    
        $(document).ready(function () {
        $('.modal_block').click(function (e) {
            $('#tn_select').empty();
            $('.modal_part').hide();
        });
        $('#modal_link').click(function (e) {
            $('.modal_part').show();
            var context = $('#tn_select').load('/Upload/UploadImage?Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id, function () {
                initSelect(context);
            });
            e.preventDefault();
            return false;
        });
    
        $('#delete_images').click(function (e) {
            var sList = "";
            $('input[type=checkbox]').each(function () {
                var sThisVal = (this.checked ? this.value : "");
                sList += (sList == "" ? sThisVal : "," + sThisVal);
            });
            $.ajax({
                url: "/Upload/DeleteImages?IDs=" + sList + '&Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id,
                data: sList,
                cache: false,
                type: "POST",
                dataType: "json"
            });
    
            reloadGallery();
            return false;
        });
    
    
        function reloadGallery() {
            $.ajax({
                type: "GET",
                url: '/Upload/Index/',
                data: "{}",
                cache: false,
                dataType: "html",
                success: function (data)
                { $().html(data); }
    
            })
    
        }
    
    });
    
    </script>
    
    <div class="modal_block modal_part"></div>
    <div class="modal_dialog modal_part" id="tn_select"></div>
    
    
    <h2>List of images</h2>
    <p>
    
        This page contains the list of all uploaded images.
    </p>
    
    
    @if (Model.ImageViewModel.Images.Count > 0)
    {
    <div class="imageContainer">
    
        <div class="div-table">
        <div class="div-table-row-title">
            <div class="div-table-col">Image</div>
            <div  class="div-table-col">Image Name</div>
        </div>
    </div>
    }
    </div>
        <div class="DeleteImages">
        <a href="#" id="delete_images">Delete Selected Images.</a>
    </div>    
    

    }
    
    else
    {
    <div class="imageCenter">
    No images have been uploaded so far.    
    </div>    
    }
    
        <p>
    <a href="#" id="modal_link">Click here to open modal dialog.</a>
    </p>
    
    <div class="clear"></div>
    

    Here is the code in the Controller to delete the images:-

            [HttpPost]
        public ActionResult DeleteImages(string IDs)
        {
            _Page = Request.QueryString["Page"];
            _Action = Request.QueryString["Action"];
            _ItemID = Convert.ToInt32(Request.QueryString["id"]);
    
            Generics.PageIDS currentPage = (Generics.PageIDS)Enum.Parse(typeof(Generics.PageIDS), _Page);
            _PageID = Convert.ToInt32(currentPage);
    
            string[] sepImageIds = IDs.Split(',');
    
            foreach (string strImageId in sepImageIds)
            {
                imageViewModel.DeleteFromXML(strImageId);
            }
    
            return RedirectToAction(_Action, _Page, new { id = _ItemID });
        }
    

    Everything works fine in this Partial View, except for when I delete an image, the deletion is done correctly, however when the code is passed back to the View, the Partial View is not refreshed.

    Is there something I am missing?

    Thanks for your help and time!

    ------------------UPDATE--------------------------------------------- This is the Edit Controller Action after the Delete has finished :-

            public ActionResult Edit(int id = 0)
        {
            articleViewModel.Article = unitOfWork.ArticleRepository.GetByID(id);
            pageViewModel.Page.PageTitle = "Article";
            pageViewModel.Page.PageAction = "Edit";
    
            if (articleViewModel.Article == null)
            {
                return HttpNotFound();
            }
    
            PopulateDropDownList(articleViewModel.Article.CategoryID);
            viewModel.ArticleViewModel = articleViewModel;
            int ImageCount = 0;
            imageViewModel.Images = imageViewModel.PopulateFromXML(pageViewModel.GetPageID(_PageName), id, out ImageCount).ToList();
            viewModel.ImageViewModel = imageViewModel;
            viewModel.PageViewModel = pageViewModel;
    
            return View(viewModel);
    
            //return Json(viewModel, JsonRequestBehavior.AllowGet);
        }