das ng-Objekt mit ng-change auswählen lassen


313

Gegeben das folgende Auswahlelement

<select ng-options="size.code as size.name for size in sizes " 
        ng-model="item.size.code" 
        ng-change="update(MAGIC_THING)">
</select>

Gibt es eine Möglichkeit, MAGIC_THING so zu gestalten, dass es der aktuell ausgewählten Größe entspricht, sodass ich Zugriff auf size.nameund size.codein meinem Controller habe?

size.code wirkt sich auf viele andere Teile der App aus (Bild-URLs usw.), aber wenn das ng-Modell von item.size.codeaktualisiert wird, item.size.namemuss es auch für Benutzer aktualisiert werden. Ich gehe davon aus, dass der richtige Weg, dies zu tun, darin besteht, das Änderungsereignis zu erfassen und die Werte in meinem Controller festzulegen, aber ich bin nicht sicher, was ich an update übergeben kann, um die richtigen Werte zu erhalten.

Wenn dies der völlig falsche Weg ist, würde ich gerne den richtigen Weg kennen.

Antworten:


488

Anstatt das ng-Modell auf item.size.code zu setzen, können Sie es auf size setzen:

<select ng-options="size as size.name for size in sizes" 
   ng-model="item" ng-change="update()"></select>

Dann wird in Ihrer update()Methode $scope.itemauf das aktuell ausgewählte Element gesetzt.

Und welcher Code auch immer benötigt wird item.size.code, kann diese Eigenschaft über erhalten $scope.item.code.

Geige .

Update basierend auf weiteren Informationen in den Kommentaren:

Verwenden Sie dann eine andere $ scope-Eigenschaft für Ihr ausgewähltes ng-Modell:

<select ng-options="size as size.name for size in sizes" 
   ng-model="selectedItem" ng-change="update()"></select>

Regler:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}

1
Wie wähle ich einen Wert vor, wenn ich mein Modell als Element einstelle?
Patrick

5
Legen Sie dies in Ihre <select>: ng-init = "item = Größen [0]"
Mark Rajcok

Vielen Dank für Ihre Hilfe, aber ich glaube nicht, dass ich genug von der Situation geteilt habe. item ist ein Objekt, das zum Laden von Seiten erstellt wird. Das Größenarray von Objekten wird bei der Benutzerinteraktion mit einer Bearbeitungsschaltfläche eingegeben. Wenn ich dies tue, wird das gesamte Elementobjekt überschrieben. Ich brauche eine Möglichkeit, eine Reihe von Optionen in einem Auswahlfeld zu erstellen, das einen Wert aus einem vollständig separaten Teil des Datenobjekts vorwählt.
Patrick

14
Ist das wahr? Es scheint, dass der ng-change-Handler ausgelöst wird, bevor das ng-Modell aktualisiert wird. Wenn Sie also $ scope.item.size.code = $ scope.selectedItem.code versuchen, erhalten Sie möglicherweise nicht immer den aktualisierten Modellwert. Hat jemand das bei der Verwendung von ng-change gesehen?
Karl

6
Vermutlich hindert Sie auch nichts daran:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden

52

Sie können den ausgewählten Wert auch direkt mit dem folgenden Code abrufen

 <select ng-options='t.name for t in templates'
                  ng-change='selectedTemplate(t.url)'></select>

script.js

 $scope.selectedTemplate = function(pTemplate) {
    //Your logic
    alert('Template Url is : '+pTemplate);
}

5
Dies beantwortet die Frage, während die akzeptierte eine Alternative gibt
redben

1
Wo initialisieren oder erhalten Sie Vorlagenvariablen?
Kat Lim Ruiz

29
Funktioniert dies ohne Angabe eines Modells? Ich erhalte die folgende Fehlermeldung: Controller 'ngModel', der von der Direktive 'select' benötigt wird, kann nicht gefunden werden!
fer

8
ngModel ist laut Dokumentation für ausgewählte Elemente unbedingt erforderlich. Die anderen Anweisungen sind optional, diese jedoch nicht.
Mnemia

26
Das funktioniert nicht! ng-change hat keinen Zugriff auf die temporäre Variable (t), die in ng-options erstellt wurde.
Müll

16

Sie können dies auch versuchen:

<select  ng-model="selectedItem" ng-change="update()">
<option ng-repeat="item in items" ng-selected="selectedItem == item.Id" value="{{item.Id}}">{{item.Name}}</option>
</select>

2
Diese Lösung ist gut, wenn Sie den Wert formatieren müssen. Mit nur dem Select-Ansatz konnte ich den Wert nicht einfach formatieren.
mbokil

7

Wenn die Antwort von Divyesh Rupawala nicht funktioniert (Übergabe des aktuellen Elements als Parameter), onChanged()lesen Sie bitte die Funktion in diesem Plunker. Es verwendet this:

http://plnkr.co/edit/B5TDQJ


2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>

11
Verwenden Sie ng-options anstelle von ng-repeat in einer Auswahl.
Jepser Bernardino

12
@JepserBernardino Manchmal benötigen Sie einen besseren Zugriff auf <Option>, z. B. um einige spezielle / Standardoptionen zu gestalten, unabhängig davon, ob sie ausgewählt sind oder nicht
Ekus

2

//Javascript
$scope.update = function () {
    $scope.myItem;
    alert('Hello');
}
<!--HTML-->
<div class="form-group">
     <select name="name"
             id="id" 
             ng-model="myItem" 
             ng-options="size as size.name for size in sizes"
             class="form-control" 
             ng-change="update()"
             multiple
             required>
     </select>
</div>

Wenn Sie schreiben möchten, Name, ID, Klasse, mehrere, erforderlich, können Sie auf diese Weise schreiben.


1

Dies könnte Ihnen einige Ideen geben

.NET C # -Modell anzeigen

public class DepartmentViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

.NET C # Web-API-Controller

public class DepartmentController : BaseApiController
{
    [HttpGet]
    public HttpResponseMessage Get()
    {
        var sms = Ctx.Departments;

        var vms = new List<DepartmentViewModel>();

        foreach (var sm in sms)
        {
            var vm = new DepartmentViewModel()
            {
                Id = sm.Id,
                Name = sm.DepartmentName
            };
            vms.Add(vm);
        }

        return Request.CreateResponse(HttpStatusCode.OK, vms);
    }

}

Winkelregler:

$http.get('/api/department').then(
    function (response) {
        $scope.departments = response.data;
    },
    function (response) {
        toaster.pop('error', "Error", "An unexpected error occurred.");
    }
);

$http.get('/api/getTravelerInformation', { params: { id: $routeParams.userKey } }).then(
   function (response) {
       $scope.request = response.data;
       $scope.travelerDepartment = underscoreService.findWhere($scope.departments, { Id: $scope.request.TravelerDepartmentId });
   },
    function (response) {
        toaster.pop('error', "Error", "An unexpected error occurred.");
    }
);

Winkelvorlage:

<div class="form-group">
    <label>Department</label>
    <div class="left-inner-addon">
        <i class="glyphicon glyphicon-hand-up"></i>
        <select ng-model="travelerDepartment"
                ng-options="department.Name for department in departments track by department.Id"
                ng-init="request.TravelerDepartmentId = travelerDepartment.Id"
                ng-change="request.TravelerDepartmentId = travelerDepartment.Id"
                class="form-control">
            <option value=""></option>
        </select>
    </div>
</div>

1

Sie müssen "Track by" verwenden, damit die Objekte korrekt verglichen werden können. Andernfalls verwendet Angular die native js-Methode zum Vergleichen von Objekten.

Ihr Beispielcode würde sich also in - ändern

    <select ng-options="size.code as size.name
 for size in sizes track by size.code" 
ng-model="item.size.code"></select>

1

AngularJS 'Filter hat für mich funktioniert.

Angenommen, das code/idist eindeutig , können wir dieses bestimmte Objekt mit AngularJS herausfiltern filterund mit den ausgewählten Objekteigenschaften arbeiten. Betrachtet man das obige Beispiel:

<select ng-options="size.code as size.name for size in sizes" 
        ng-model="item.size.code" 
        ng-change="update(MAGIC_THING); search.code = item.size.code">
</select>

<!-- OUTSIDE THE SELECT BOX -->

<h1 ng-repeat="size in sizes | filter:search:true"
    ng-init="search.code = item.size.code">
  {{size.name}}
</h1>

Nun gibt es drei wichtige Aspekte dazu :

  1. ng-init="search.code = item.size.code"- Setzen Sie beim Initialisieren des h1Elements außerhalb des selectFelds die Filterabfrage auf die ausgewählte Option .

  2. ng-change="update(MAGIC_THING); search.code = item.size.code"- Wenn Sie die Auswahleingabe ändern, wird eine weitere Zeile ausgeführt, in der die Suchabfrage auf die aktuell ausgewählte gesetzt wird item.size.code.

  3. filter:search:true- trueZum Filter übergeben, um eine strikte Übereinstimmung zu ermöglichen .

Das ist es. Wenn das size.codeist uniqueID , wir haben nur ein h1Element mit dem Text size.name.

Ich habe dies in meinem Projekt getestet und es funktioniert.

Viel Glück


0

Dies ist der sauberste Weg, um einen Wert aus einer Liste mit Winkelauswahloptionen (außer The Id oder Text) abzurufen. Angenommen, Sie haben eine Produktauswahl wie diese auf Ihrer Seite:

<select ng-model="data.ProductId"
        ng-options="product.Id as product.Name for product in productsList"
        ng-change="onSelectChange()">
</select>

Stellen Sie dann in Ihrem Controller die Rückruffunktion wie folgt ein:

    $scope.onSelectChange = function () {
        var filteredData = $scope.productsList.filter(function (response) {
            return response.Id === $scope.data.ProductId;
        })
        console.log(filteredData[0].ProductColor);
    }

Einfach erklärt: Da das Ereignis ng-change die Optionselemente in der Auswahl nicht erkennt, verwenden wir das ngModel, um das ausgewählte Element aus der im Controller geladenen Optionsliste herauszufiltern.

Da das Ereignis ausgelöst wird, bevor das ngModel wirklich aktualisiert wird, erhalten Sie möglicherweise unerwünschte Ergebnisse. Ein besserer Weg wäre also, eine Zeitüberschreitung hinzuzufügen:

        $scope.onSelectChange = function () {
            $timeout(function () {
            var filteredData = $scope.productsList.filter(function (response) {
                return response.Id === $scope.data.ProductId;
            })
            console.log(filteredData[0].ProductColor);
            }, 100);
        };
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.