Laden...

Javascript-Funktion wird (nur) im IE nur einmal ausgeführt

Erstellt von Mary81 vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.219 Views
M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 6 Jahren
Javascript-Funktion wird (nur) im IE nur einmal ausgeführt

Hallo,

ich habe eine Web-Applikation.

Alles läuft einwandfrei unter Chrome, Firefox, Edge. Aber Internet Explorer macht Probleme.... es ist aber wichtig das es im IE läuft 😦

wenn ich auf einen Button klicke sollte eine function angesprochen werden...


function AktualisiereView(viewObject, acName) {
        $.ajax({
            url: acName,
            type: "get"
        }).done(function (data) {                
            $("#" + viewObject).html(data);
        }).fail(function () {
            Fehler("Fehler: es wurde ein Fehlerausgelöst!");
        });
 }

function OnFunctionTest(Id) {
        $.ajax({
            type: "GET",
            url: "@(Url.Action("ChangedABC", "Home"))",
            data: { nr: Id },
            success: function (data) {
                if (data.success) {
                    AktualisiereView('div-xyz', "@(Url.Action("RefreshView", "Home"))");
                }
            }
        });
    }

... das ist was ausgeführt werden soll ....
IE führt es nur einmal durch, auch wenn ich dann noch 100 mal auf den Button klicke, passiert nix...

Wenn ich das Element untersuche (F12), dann ändert sich der Code im HTML-Tag ...

function OnFunctionTest(Id) {
        $.ajax({
            type: "GET",
            url: "/Home/ChangedABC",
            data: { nr: Id },
            success: function (data) {
                if (data.success) {
                    AktualisiereView('div-xyz', "/Home/RefreshView");
                }
            }
        });
    }

Weiß jemand wieso es nicht mehr funktioniert wenn es einmal ausgeführt wurde???

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo,

Weiß jemand wieso es nicht mehr funktioniert wenn es einmal ausgeführt wurde???

Nein. Aber eine Vermutung hätte ich anzubieten:
Wie sieht denn die Stelle aus, an der Du die Funktion an das click-Ereignis des Buttons hängt?
Möglicherweise hast Du da einen Funktions_aufruf_ stehen, statt die Funktion als Handler zuzuweisen.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 6 Jahren

Hi,

über ein Bild wird das click-event ausgelöst...


<div id="div_img_del">
    <img class="image-menue" src="/Content/Images/Delete.png" onclick="OnFunctionTest(55)"  />
</div>

Vielen Dankl

16.806 Beiträge seit 2008
vor 6 Jahren

Keine gute Idee.

Wenn Du schon mit jQuery arbeitest, dann nutze einfach dessen Event Binder.
.on() | jQuery API Documentation

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 6 Jahren

Hallo Abt,

hab's ausprobiert wie es in der jQuery Docu steht, aber es scheint nicht zu helfen. Das Problem besteht, ich kann es nur einmal ausführen, danach funktioniert es nicht mehr.

Vielleicht habe ich einen falschen Ansatz:

Ich setzte das MVC-Model an, sprich ich habe ein Model in der ich eine Liste von Daten. Diese werden in der View per foreach-Schleife zur anzeige gebracht....


...
            @{int x = 0;}
            @foreach (var asset in Model.ListeABC.OrderBy(b=> b.Nr).Take(10))
            {
                x++;
                <tr class="tr_bl_@x" onmousemove="SelectedTableRowMove('tr_bl_@x')" onmouseout="SelectedTableRowOut('tr_bl_@x')">
                    <td>
                        <div id="div-img-nr-@asset.Nr" class="pad"><b>@asset.Nr</b></div>
                    </td>
                    <td>
                        <div>
                            @Html.DropDownListFor(m => asset.StatusID, new SelectList(Model.StatusList, "StatusID", "Bezeichnung", asset.StatusID), new { @class = "form-control asset-bs-" + asset.Nr, onchange="OnChangeBearbStatus(" + asset.Nr + ")" })
                        </div>
                    </td>
                    <td>
                        <div id="div_img_del">
                            <img class="image-menue" src="/Content/Images/Delete_anthrazit.png" onclick="Delete(@asset.Nr)"  />
                        </div>
                    </td>
                </tr>
            }
    ....

Wenn ich dann auf das Delete-Bild klicke sollte der Eintrag aus der Liste im Model gelöscht werden. Das habe ich mit der Funktion


function OnFunctionTest(Id) {
        $.ajax({
            type: "GET",
            url: "@(Url.Action("ChangedABC", "Home"))",
            data: { nr: Id },
            success: function (data) {
                if (data.success) {
                    AktualisiereView('div-xyz', "@(Url.Action("RefreshView", "Home"))");
                }
            }
        });
    }

umgesetzt.

Vielleicht gibt es ja einen anderen Weg, bin auch noch nicht solange in der ASP-Programmierung drin. Vielleicht habe ich deswegen Probleme!?

Wenn jemand vielleicht einen bessern Ansatz kennt???

Ich bin für jeden Vorschlag dankbar, denn ich weiß einfach nicht mehr weiter.

16.806 Beiträge seit 2008
vor 6 Jahren

Ich sehe hier allerlei Dinge, die man in MVC so nicht macht (aber das ist mal nebensächlich), aber ich seh hier nirgends jQuery.on().
Ebenso sprichst Du nur von "geht nicht", was keinem weiter hilft. Welcher Fehler taucht auf der Console auf (F12: Developer Tools).

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 6 Jahren

Ich bin neu im asp, habe vorher mit WPF und Windows Forms gearbeitet.

Ich habe keine konkrete Fehlermeldung.... mein Problem ist wirklich, dass das Event (klicken auf das Bild) nur einmal ausgeführt wird und nur im Internet Explorer. Im Chrome, Firefox und Edge funktioniert es.

Vielleicht habe ich das ganze falsch angefangen. Im Netz gibt's 1000 Sachen über MVC und ASP.net aber ich habe für mich keinen konkreten lernreichen Beispiel gefunden, nach welchem ich mein Projekt aufbauen konnte.

Habe also versucht, dass so zu entwickeln das ich eine View-Model-Data (ähnlich wie im WPF) habe.

Somit verwende ich HTML, JavaScript und Ajax aufrufe zum Controller. Wo ich dann die Aktualisierungen /Änderungen in meinem Model vornehme und das Model im View dann aktualisiere.

Wenn du vielleicht einen link hast, wo das mit mvc beschrieben ist, wie man es heutzutage macht, wäre ich dir echt dankbar dafür.

Vielleicht löst sich ja mein Problem auch, wenn ich es anders (richtig) mache.

16.806 Beiträge seit 2008
vor 6 Jahren

Moderne Webanwendungen bestehen heutzutage aus zwei Anwendungen: Server (zB ASP.NET) und Client (zB ein Browser, eben JavaScript).

Genau so solltest Du eigentlich auch entwickeln: MVC und JavaScript getrennt.
Sprich Du solltest das JavaScript in eigene Dateien auslagern und nicht mit dem HTML Teil vermischen. Das ist ja genau das, was Pattern wie MVVM und MVC ausmachen; die Trennung.

Den JavaScript Teil kann man dann mit verschiedenen Frameworks umsetzen: JQuery, Angular, Aurelia.
In Deinem Fall ist er ja nur dazu da, dass ein wenig Dynamik in die Seiten kommt.

Ergo kann man zB also via jQuery pro ASP.NET Page Attribut nutzen, in dem dann die Events greifen:

<!-- ASP Seiten Anfang -->
<div data-page-name="PersonListView">
 Dein HTML Zeugs hier

<div id="div_img_del">
    <img class="image-menue" src="/Content/Images/Delete.png" onclick="OnFunctionTest(55)"  />
</div>
</div>
<!-- ASP Seiten Ende-->

$('[data-page-name="PersonListView"] div#div_img_del img').on('click', function()
{
  // code on click here
})

Dies brauchst Du, damit die Events auch nur dort greifen, wo sie sollen, und nicht zB auf allen Seiten.

Willst Du es weiterhin alles (HTML und JavaScript) vermischen, dann muss Dein Event eher so lauten:

$('div#div_img_del img').on('click', function()
{
  // code on click here
})

Oder

$('div#div_img_del').on('click', 'img', function()
{
  // code on click here
})

Wenn Du den Handler auf das Parent Element (das div) und nicht auf img haben willst.

Was Du bisher vesucht hast können wir nur raten, weil Du es nicht wirklich zeigst.

PS: in ASP.NET musst Du komplett anders, viel abstrakter vorgehen als in WPF oder WinForms.
Es ist eine völlig andere Technologie, die auch ein anderes Denken erfordert.

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 6 Jahren

du hast recht. Das von einander zu trenne macht ja sinn, ich komme da aber mit meinem Wissen nicht weiter....

eine Teilansicht von mir, sieht wie folgt aus...


@model SIM.Client.Models.ViewModel.Sitzung.Bearbeitungsstatus.BearbeitunsstatusViewModel

<div id="bearbeitungsstatus">
    <table id="assets-data-table-status" class="table table-striped" style="width:220px;">
        <thead>
            <tr>
                <th style="width:20px;"></th>
                <th>Bearbeitungsstatus</th>
                <th style="width:20px;">
                    <div id="div_img_addtop">
                        <img class="image-menue" id="status-img-add" src="/Content/Images/ZoomIn_anthrazit.png" onclick="AddBearbeitungsstatus()" />
                    </div>
                </th>
            </tr>
        </thead>
        <tbody>
            @{int x = 0;}
            @foreach (var asset in Model.Bearbeitunsstatus.Where(w => w.Nr >= Model.NavigationVM.StartIndexListe).OrderBy(b=> b.Nr).Take(10))
            {
                x++;
                <tr class="tr_bl_@x" onmousemove="SelectedTableRowMove('tr_bl_@x')" onmouseout="SelectedTableRowOut('tr_bl_@x')">
                    <td>
                        <div id="div-img-nr-@asset.Nr" class="pad"><b>@asset.Nr</b></div>
                    </td>
                    <td>
                        <div>
                            @Html.DropDownListFor(m => asset.StatusID, new SelectList(Model.StatusList, "StatusID", "Bezeichnung", asset.StatusID), new { @class = "form-control asset-bearbeitungsstatus-" + asset.Nr, onchange="OnChangeBearbStatus(" + asset.Nr + ")" })
                        </div>
                    </td>
                    <td>
                        <div id="div_img_del">
                            <img class="image-menue" src="/Content/Images/Delete_anthrazit.png" onclick="DeleteBearbeitungsstatus(@asset.Nr)"  />
                        </div>
                    </td>
                </tr>
            }
        </tbody>
    </table>
          
</div>

<script type="text/javascript">

    function AktualisiereView(viewObject, acName) {
        $.ajax({
            url: acName,
            dataType: "json",
            type: "get"
        }).done(function (data) {
            $("#" + viewObject).html(data);
        }).fail(function () {
            alert("Fehler: es wurde ein Fehlerausgelöst!");
        });
    }

    function AktualisiereBearbeitungsstatusView() {
        AktualisiereView('div-bearbeitungsstatus', "@(Url.Action("BearbeitungsstatusRefreshView", "Sitzung"))");
        AktualisiereView('div-navigation-bearbeitungsstatus', "@(Url.Action("NavigationRefreshView", "Sitzung"))?lid=bearbeitungsstatus");
    }

    function OnChangeBearbStatus(anr) {
        $.ajax({
            type: "GET",
            url: "@(Url.Action("ChangedBearbeitunsstatusData", "Sitzung"))",
            data: { nr: anr, id: $('.asset-bearbeitungsstatus-' + anr).val() },
            success: function (data) {
                if (data.success) {
                    AktualisiereView('div-bearbeitungsstatus', "@(Url.Action("BearbeitungsstatusRefreshView", "Sitzung"))");
                }
            }
        });
    }

    function AddBearbeitungsstatus() {
        $.ajax({
            type: "POST",
            url: '@Url.Action("InsertBearbeitunsstatusData", "Sitzung", null, Request.Url.Scheme, null)',
            cache: false,
            success: function (data) {
                alert("jetzt...");
                if (data.success) {
                    AktualisiereBearbeitungsstatusView();
                }
            }
        });
    }

    function DeleteBearbeitungsstatus(assetnr) {
        $.ajax({
            type: "GET",
            url: "@(Url.Action("DeleteBearbeitunsstatusData", "Sitzung"))",
            data: { nr: assetnr },
            success: function (data) {
                if (data.success) {
                    AktualisiereBearbeitungsstatusView();
                }
            }
        });
    }
    
</script>

Der Controller...


public ActionResult BearbeitungsstatusView()
        {
            return PartialView();
        }

        [HttpGet]
        public ActionResult BearbeitungsstatusRefreshView()
        {
            return PartialView("BearbeitungsstatusView", _viewModel.GVM.BearbeitunsstatusVM);
        }

        [HttpGet]
        public ActionResult DeleteBearbeitunsstatusData(int nr)
        {
            bool addSuccess = _viewModel.GVM.BearbeitunsstatusVM.DeleteStatusRow(nr);
            return Json(new { success = addSuccess }, JsonRequestBehavior.AllowGet);
        }
        
        [HttpGet]
        public JsonResult InsertBearbeitunsstatusData()
        {
            bool addSuccess = _viewModel.GVM.BearbeitunsstatusVM.AddStatusRow();
            return Json(new { success = addSuccess }, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public JsonResult ChangedBearbeitunsstatusData(int nr, int id)
        {
            _viewModel.GVM.BearbeitunsstatusVM.OnChanged(nr, id);
            return Json(new { success = true }, JsonRequestBehavior.AllowGet);
        }

das Model....


public class BearbeitunsstatusViewModel : BaseViewModel
    {
        EntityManager UM = new EntityManager();

        public BearbeitunsstatusViewModel(int gID)
        {
            GID = gID;
            StatusList = UM.TableToList.Status;
            Bearbeitunsstatus = UM.BearbeitunsstatusLaden(gID);
        }

        private int GID { get; set; }
        
        public List<StatusListe> StatusList { get; set; }
        
        public List<BearbeitungsstatusListe> Bearbeitunsstatus { get; set; }

        internal bool AddStatusRow()
        {
            var nextStatusID = 0;
            if (Bearbeitunsstatus.Count > 0)
            {
                var maxNr = Bearbeitunsstatus.Where(w=> w.StatusID > 0).Max(m => m.Nr);
                var istID = Bearbeitunsstatus.First(w => w.Nr == maxNr).StatusID;
                var sortierung = StatusList.First(w => w.StatusID == istID);
                var next = StatusList.Where(w => w.Sortierung > sortierung.Sortierung).OrderBy(o => o.Sortierung);
                nextStatusID = next.Count() > 0 ? next.First().StatusID : 0;
                nextStatusID = Bearbeitunsstatus.Count(w => w.StatusID == nextStatusID) == 0 ? nextStatusID : 0;
            }
            else
                nextStatusID = StatusList.Where(w => w.Sortierung > 0).OrderBy(w => w.Sortierung).First().StatusID;

            var neu = new BearbeitungsstatusListe();
            neu.GID = GID;
            neu.ID = 0;
            neu.StatusID = nextStatusID;
            neu.Nr = Bearbeitunsstatus.Count > 0 ? Bearbeitunsstatus.Max(w => w.Nr) + 1 : 1;
            Bearbeitunsstatus.Add(neu);
            AenderungVorhanden = true;
                        
            return true;
        }

        internal bool DeleteStatusRow(int nr)
        {
            var d = Bearbeitunsstatus.FirstOrDefault(w => w.Nr == nr);
            Bearbeitunsstatus.Where(w => w.Nr > nr).ToList().ForEach(i => i.Nr = i.Nr - 1);
            if (d != null)
            {
                AenderungVorhanden = true;
                Bearbeitunsstatus.Remove(d);
                
                return true;
            }
            else return false;
        }

        internal void OnChanged(int nr, int id)
        {
            foreach (var b in Bearbeitunsstatus.Where(w => w.Nr == nr))
            {
                b.StatusID = Bearbeitunsstatus.Count(w => w.StatusID == id) == 0 ? id : 0;
                AenderungVorhanden = true;
            }
        }
    }

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo Mary81,

wenn du eine SPA entwickeln willst solltest du Richtung WebAPI/Client Side Frameworks gehen, wie von Abt schon genannt. Auch auf die Gefahr hin dich mehr zu verwirren denke ich, dass Einstieg in Webprogrammierung: ASP.NET MVC oder Webforms? hilfreich sein könnte.

Gruss

Coffeebean

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 6 Jahren

Die Verwiegung ist groß :0

Das ist ein wirklich sehr umfangreiches Thema....

Ich habe jetzt versucht HTML und JavaScript von einander zu trennen.
Soweit funktioniert das auch schon, aber .... noch einmal zu Verständnis.... wie komme ich denn jetzt in meinen Cotroller, wenn ich die Änderungen abspeichern möchte???

Der JavaScript-Code ist jetzt in einer MyJS.js


(function ($) {

    $('[data-page-name="BearbeitunsstatusViewModel"] div#div_img_del img').on('click', function () {

        (hier ???????????????)
        $.ajax({
            type: "GET",
            url: "@(Url.Action("Action", "Controller"))",
            .......
    });
   
}(jQuery));


oder sollte ich an der Stelle gar nicht mit Ajax arbeiten?

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo Mary81,

was du gerade machst ist eine SPA mit jQuery. AJAX las Konzept zu verwenden ist schon in Ordnung. Aber das Problem ist eine Architektur mit jQuery zu machen. Das ist schlichtweg brutal schwer, wenn nicht unmöglich. Wenn du in Richtung einer SPA willst, schau dir Angular, React oder oder oder an. Ajax ist ein Konzept und geht auch ohne jQuery.

Gruss

Coffeebean