W mojej firmie budujemy aplikację internetową dla systemu fakturowania, który wykorzystuje pasek powiadomień, podobny do Facebooka, przy czym użytkownik może upuścić menu, który wyświetla status transakcji w systemie, podczas gdy łączna liczba pozostałych transakcji Wyświetla obok niego. Zobacz zdjęcie, aby uzyskać szczegółowe informacje.

http://img210.Imageshack.us/img210/4379/alertdrop.png.

Pobieramy dane dla tego za pomocą następującego kodu dla tabeli w menu rozwijanym:

<table id="alertDropTable" style="margin-top:10px;">

    @{
        Dictionary<string, int> dic = ViewBag.statusCount;
        if (dic != null)
        {
            for (int i = 0; i < dic.Count; i++)
            {
                if (dic.Values.ElementAt(i) > 0)
                {
                    <tr>
                        <td width="100%" style="padding-bottom:4px; padding-top:4px; padding-left:10px; padding-right:10px; vertical-align:middle;">
                            You have <strong><a style="background-color:#878787; border-radius:5px; color:White; padding:3px;">@dic.Values.ElementAt(i)</a></strong> @dic.Keys.ElementAt(i) transaction(s).
                        </td>
                    </tr>
                }
            }
        }
    }

</table>

I następujące dla rozpiętości, który wyświetla łącznie:

<div style="float: left;">
    <a href="javascript:;" onmouseover="document.alert.src='@Url.Content("~/Content/images/alert_notification_hover.png")'" onmouseout="document.alert.src='@Url.Content("~/Content/images/alert_notification.png")'" onclick="toggle('notificationDrop');"><img src="@Url.Content("~/Content/images/alert_notification.png")" name="alert" alt="alert"/></a>

            @{
                Dictionary<string, int> dicheader = ViewBag.statusCount;
                int diccount = 0;
                if (dicheader != null)
                {
                    for (int i = 0; i < dicheader.Count; i++)
                    {
                        if (dicheader.Values.ElementAt(i) > 0)
                        {
                            diccount = diccount + @dicheader.Values.ElementAt(i);
                        }
                    }
                }
            }

    </div>

    <div id="alertTotalDiv" style="float:left;margin-top:6px; margin-left:5px;"><span id="alertTotal" style="vertical-align:middle; background-color:#878787; border-radius:5px; color:White; font-family:Georgia; font-size:20px; padding:3px; padding-left:5px; padding-right:5px;margin-top:0px;">@diccount</span></div>

Ten kod jest obecnie zapisany w pliku Global "_layout.cshtml". Wybacz szorstkość kodu, jest to bardzo wczesna wersja. Jednak działa dobrze pod względem pobierania danych na obciążeniu strony. Jednak system wymaga automatycznie aktualizacji tych informacji co kilka sekund bez odświeżenia całej strony. W istocie, dokonując połączenia do sterownika, aby przywrócić bieżące dane i zaktualizować <table> i <span> z bieżącymi wartościami.

Zostałem poproszony o utworzenie funkcji AJAX, która pobiera dane z "Alertcontroller" i odpowiednio aktualizuje widok. Proszę znaleźć zawartość tego kontrolera poniżej:

public class AlertController : Controller
{

    /// <summary>
    /// Gets or sets the user service contract.
    /// </summary>
    /// <value>The user service contract.</value>
    public IUserServiceContract UserServiceContract { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="BaseController"/> class.
    /// </summary>
    protected AlertController()
    {
        this.UserServiceContract = Gateway.Instance.Resolve<IUserServiceContract>();

    }

    /// <summary>
    /// Get the AlertTypes
    /// </summary>
    /// <returns></returns>
    public virtual void ViewAlerts()
    {
        Gateway.Instance.Logger.LogInfo(string.Format("Overview Controller View:    Fetching list of alerts."));

        try
        {
            if (this.UserServiceContract != null)
            {
                var allAnnouncements = this.UserServiceContract.GetAnnoucements();
                var userAlertSettings = this.UserServiceContract.GetUserAlert();


                ViewBag.statusCount = userAlertSettings;
                ViewBag.announcements = allAnnouncements.ToList();
            }
        }
        catch (Exception ex)
        {
            Gateway.Instance.Logger.LogInfo(ex);
            throw new Exception(string.Format("Home Controller View Error:  {0} occured while fetching alerts.", ex.Message), ex);
        }
    }

Jestem zakłopotany, ale otrzymałem następujący przykład funkcji AJAX, która jest używana do wykonania innego zadania całkowicie, aby mi pomóc:

$.ajax({
    url: '@Url.Action("ViewAlerts", "Alerts")',
    data: { ownerIds: ownerIds },
    traditional: true,
    dataType: 'json',
    success: function (result) {
        for (i = 0; i < ownerIds.length; i++) {
            $(".ownersTable tr[id='tablerow+" + ownerIds[i] + "']").remove();
        }
    },
    error: function (xhr, ajaxOptions, thrownError) {
        $("#confirmDiv").alertModal({
            heading: '@Language.Fail',
            body: '@Language.AlertRemoveOwnerFailed' + thrownError
        });
    }
});

Do tej pory jedyną rzeczą, którą udało mi się pracować, była ustawiona funkcja interwału, która tworzy alarm co 5 sekund!

Jakieś wskazówki dotyczące tego?

0
Nick Chambers 31 sierpień 2012, 18:47

3 odpowiedzi

Najlepsza odpowiedź

Dobra, to właśnie będziesz musiał zrobić, przede wszystkim:

$.ajax({
    url: '@Url.Action("ViewAlerts", "Alerts")', 
    data: { ownerIds: ownerIds },
    traditional: true,
    dataType: 'json',
    success: function (result) {
        for (i = 0; i < ownerIds.length; i++) {
            $(".ownersTable tr[id='tablerow+" + ownerIds[i] + "']").remove();
        }
    },
    error: function (xhr, ajaxOptions, thrownError) {
        $("#confirmDiv").alertModal({
            heading: '@Language.Fail',
            body: '@Language.AlertRemoveOwnerFailed' + thrownError
        });
    }
});

Dlaczego adres URL.Action w cytatach? Wystarczy umieścić @ URL.Action ... Nie widzę powodu cytatów i może przebić połączenie.

Po drugie z wszystkich nie używaj ViewBag. Nie powinno być tak naprawdę używane do przechowywania "danych" (moim zdaniem). Powinieneś użyć modelu. Więc to możesz zrobić:

Utwórz część strony, którą chcesz zaktualizować do "częściowego widoku", który jest silnie wpisany do modelu, który zawiera status i ogłoszenia i wszystko, czego potrzebujesz.

Użyj jQuery, aby "załadować" metodę kontrolera, która otrzyma dane i zwróci ten "widok częściowy" i załaduj go do div na ekranie Przykład:

$('#div-to-load-into').load('/myactionurl/', function () { //Do something when done });

Więc twój kontroler zostanie następnie nazywany, otrzymuje dane i zwraca widok częściowy z utworzonym modelem!

Powodzenia!

--- Edytuj --- Powinieneś wykonać powyżej, ponieważ byłoby łatwiejsze i szybsze (a jeśli osiągniesz przeprojektowanie, szybko to zrozumiesz, ale oto pomysł, jak zrobić to, co chcesz)

To jest to, co musisz wiedzieć,

URL to akcja, że AJAX zadzwonił. Musisz umieścić adres URL: "/ Controller / Action"

Dane to dane wysyłane do tej akcji {Nazwa parametry: parametr} Wygląda na to, że w twoim przypadku wysyłanie żadnych danych, ponieważ tylko odpytywanie dla odświeżania, więc nie musisz zawierać to

DataType to dane, które spodziewasz się, że można zwrócić, może być "HTML" lub "JSON", w twoim przypadku nic nie powracającego, ponieważ używasz "ViewBag"

Sukces zostanie wywołany, jeśli połączenie AJAX zostało pomyślnie wezwane bez błędów w wyniku tego w "wyniku", w twoim przypadku nie masz wyniku, ponieważ przy użyciu torby widoku.

Teraz nie mogę obiecać, że to będzie działać, ponieważ nigdy tego nie próbowałem:

function(result)
{
var updated_values = @Html.Raw(Json.Encode(ViewBag.AlertStatus)) 
}

Wewnątrz funkcji sukcesu na AJAX spróbuj tego, może to nie działać. Szczerze mówiąc, nie wiem, czy ViewBag będzie miał zaktualizowane wartości, czy nie. W tym momencie musisz jedynie zastąpić wartości tabeli z nowymi! Będziesz musiał zrobić to wszystko w JavaScript, a ja proponuję patrzeć na funkcje, takie jak "Appendto", "Wymiana", "HTML", które są w jQuery, aby dowiedzieć się, jak to zrobić.

$.ajax({
    url: 'controller/action', 
    success: function (result) {
        var alert_info = @Html.Raw(Json.Encode(ViewBag.AlertStatus)) 
    },
    error: function (xhr, ajaxOptions, thrownError) {
        //error handling
    }
});
1
AwDogsGo2Heaven 31 sierpień 2012, 16:24
(function checkStatus() {
  $.ajax({
    url: '@Url.Action("ViewAlerts", "Alerts")', 
    data: { ownerIds: ownerIds },     
    traditional: true,     
    dataType: 'json',
    success: function (result) 
    {         
      for (i = 0; i < ownerIds.length; i++) 
       {             
         $(".ownersTable tr[id='tablerow+" + ownerIds[i] + "']").remove();
       }     
    },
    complete: function() {
      // Schedule the next request when the current one's complete
      setTimeout(checkStatus, 5000);
    }
  });
})();

Jak okresowo wystrzelić żądanie Ajax?

0
Community 23 maj 2017, 12:20

Aby uzyskać dane z akcji do JavaScript, Twoja akcja musi zwrócić dane. W tej chwili twoje "akcja" nie jest naprawdę akcją, ponieważ zwraca void i ustawia ViewBag właściwości, które nie są dostępne z JavaScript. Więc twoja akcja musi być czymś więcej:

[HttpGet]
public ActionResult Alerts()
{
    IEnumerable alerts;
    // ...code which gets data into alerts
    return JsonResult(alerts);
}

Oczywiście nie znam twojej domeny, więc nie wiem, jak struktur powracający dane, ale podstawy są tam. Call $.ajax Wskazuje na trasę akcji (w tym przypadku, prawdopodobnie '/Alert/Alerts'). Funkcja success miałaby argument data z odpowiednią tablicą obiektów. Stamtąd zaktualizowałeś swój dom z danymi.

0
Heretic Monkey 31 sierpień 2012, 16:46