Hur implementerar man seriekopplade rullgardinsmenyer (som behöver göra anrop mot backend för att visa korrekta alternativ; t ex Land – Städer) med AngularJS och ASP.NET MVC

Inledning

[Källa]

[GitHub repo]

I den här laborationen kommer vi att se hur man kan implementera seriekoppladde rullgardinsmenyer.

Ibland är det nödvändigt att hålla ett beroende mellan dropdownlistor på en websida; ett valt värde i en lista ska påverka vad som skall visas i en annan lista. Det finns åtskilliga exempel på vad man kan använda det här till men bara för att ta något så skulle man kunna ha ”Länder” i en lista resp ”Landets städer” i en annan.

I laborationen kommer vi att använda oss av AngularJS direktiv ng-change. Detta övervakar värdeförändringar på <input>-element och gör så att vår AngularJS-applikation kan reagera på förändringen. Det är precis vad vi kommer att göra i den här applikationen.

Steg

  1. Skapa två ny tabeller i databasen [här Country resp State]

    Öppna databasen > Högerklicka på Table > Add New Table > Add Columns > Save > Tilldela repektive skapad tabell varsitt namn > Ok.

  2. Uppdatera dataentitetsmodellen

    Gå till Solution Explorer > Öppna dataentitetsmodellen [här ContactsModel.edmx] > Högerklicka på en tom yta i den för att få fram context-menyn > Update Model From Database… > Nu får vi fram ett pop-up-fönster (Entity Data Model Wizard) > Välj Tables > Finish.

  3. Lägg till en ny ny Action i DataController som hämtar en lista med Countries från databasen och returnerar den som ett JsonResult

    // Hämta Countries
    public JsonResult GetCountries()
    {
        List<Countries> allCountry = new List<Countries>();
        using (MyDatabaseEntities dc = new MyDatabaseEntities())
        {
            allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
        }
        return new JsonResult { Data = allCountry, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
    }
    
  4. Lägg till en ny ny Action i DataController som hämtar en lista med States, med hänsyn tagen till ett visst CountryId, från databasen och returnerar den som ett JsonResult

    // Läs in States by CountryId
    public JsonResult GetStates(int countryID)
    {
        List<States> allState = new List<States>();
        using (MyDatabaseEntities dc  = new MyDatabaseEntities())
        {
            allState = dc.States.Where(a => a.CountryID.Equals(countryID)).OrderBy(a => a.StateName).ToList();
        }
        return new JsonResult { Data = allState, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
    }
  5. Lägg till en ny front-end Control (en /Scripts/AngularController/.js-fil)

    Gå till Solution Explorer > Högerklicka på foldern där AngularJS-javascriptfilerna ska sparas [här /Scripts/AngularController/] > Add > Välj JavaScript File > Ange ett namn [här Part5Controller.js]

    angular.module('MyApp')
    .controller('Part5Controller', function ($scope, LocationService) {
        $scope.CountryId = null;
        $scope.StateId = null;
        $scope.CountryList = null;
        $scope.StateList = null;
        $scope.StateTextToShow = "Välj Stat";
        $scope.Result = "";
        // Populera Country
        LocationService.GetCountry().then(function (d) {
            $scope.CountryList = d.data;
        }, function (error) {
            alert('Error!');
        });
        // Function For Populate State 
        // Funktion för att populera $scop-variabeln med befintliga Stater
        // (den här funktionen kommer att anropas först när vi har valt namn)
        $scope.GetState = function () {
            $scope.StateId = null; // Töm vald Stat (om sådan valts)
            $scope.StateList = null; // Tö eventuell tidigare hämtad lista med Stater
            $scope.StateTextToShow = "Please Wait..."; // det här meddelandet kommer att visas till dess att Stater har hämtats
            //Hämta stater
            LocationService.GetState($scope.CountryId).then(function (response) {
                $scope.StateList = response.data;
                $scope.StateTextToShow = "Select State";
            }, function (error) {
                alert('Error!');
            });
        }
        // Funktion som visar resultatet
        $scope.ShowResult = function () {
            $scope.Result = "Selected Country ID : " + $scope.CountryId + " State ID : " + $scope.StateId;
        }
    })
    .factory('LocationService', function ($http) { 
        var fac = {};
        fac.GetCountry = function () {
            return $http.get('/Data/GetCountries');
        }
        fac.GetState = function (countryId) {
            return $http.get('/Data/GetStates?countryID=' + countryId);
        }
        return fac;
    });

    Observera att variabelnamn på klientsidan är skiftlägeskänsliga. Följande javascript kommer alltså inte att funka:

    function (countryId) {
        return $http.get('/Data/GetStates?countryID=' + countryID);
    }

    Browsern kommer inte att generera någon varning heller!

  6. Lägg till en ny Action i backend HomeController som renderar View Part5.cshtml

    public ActionResult Part5() // Implementation av seriekopplad DropDownList
    {
        return View();
    }
  7. Skapa View Part5.cshtml

    Högerklicka på Action metoden som ska rendera Part5.cshtml > Add View… > Ange ett namn på den View som ska skapas > Add

    @{
        ViewBag.Title = "Part5";
    }
    <h2>Seriekopplade rullgardinsmenyer med AngularJS och MVC4</h2>
    
    Country : Välj Country State : {{StateTextToShow}}
    {{Result}}
    </div> @section scripts{ http://~/Scripts/AngularController/Part5Controller.js }
  8. Exekvera projektet!

Annonser