obtener el objeto ng seleccionado con ng-change

313

Dado el siguiente elemento de selección

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

¿Hay una manera de conseguir MAGIC_THING ser igual al tamaño seleccionado en ese momento, así que no tengo acceso a size.name, y size.codeen el controlador?

size.code afecta a muchas de las otras partes de la aplicación (URL de imágenes, etc.), pero cuando item.size.codese actualiza el modelo ng de , también item.size.namedebe actualizarse para el usuario que enfrenta cosas. Supongo que la forma correcta de hacer esto es capturar el evento de cambio y establecer los valores dentro de mi controlador, pero no estoy seguro de qué puedo pasar a la actualización para obtener los valores adecuados.

Si esta es la manera completamente incorrecta de hacerlo, me encantaría saber la forma correcta.

Patricio
fuente

Respuestas:

488

En lugar de configurar el modelo ng en item.size.code, ¿qué tal si lo configura en tamaño?

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

Luego, en su update()método, $scope.itemse establecerá en el elemento seleccionado actualmente.

Y cualquier código necesario item.size.code, puede obtener esa propiedad a través de $scope.item.code.

Violín .

Actualización basada en más información en los comentarios:

Utilice alguna otra propiedad $ scope para su modelo ng seleccionado y luego:

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

Controlador:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}
Mark Rajcok
fuente
1
Si configuro mi modelo como elemento, ¿cómo preselecciono un valor?
Patrick
55
Ponga esto dentro de su <select>: ng-init = "item = tamaños [0]"
Mark Rajcok
Muchas gracias por su ayuda, pero no creo que haya compartido la situación lo suficiente. El elemento es un objeto que se crea carga de página. la matriz de tamaños de objetos entra en interacción con el usuario con un botón de edición, por lo que si hago esto, anulará todo el objeto del elemento. Necesito una forma de crear un montón de opciones en un cuadro de selección que preseleccione un valor de una parte completamente separada del objeto de datos.
Patrick
14
¿Es esto cierto? Parece que el controlador ng-change se dispara antes de que se actualice el modelo ng, por lo que probar $ scope.item.size.code = $ scope.selectedItem.code no siempre le dará el valor del modelo actualizado. ¿Alguien ha visto eso al usar ng-change?
Karl
66
Supongo que tampoco hay nada que te impida hacer esto:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden
52

También puede obtener directamente el valor seleccionado utilizando el siguiente código

 <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);
}
Divyesh Rupawala
fuente
55
Esto responde a la pregunta mientras que la aceptada ofrece una alternativa
redben
1
¿Dónde se inicializa u obtiene la variable de plantilla?
Kat Lim Ruiz
29
¿Funciona esto sin especificar un modelo? Recibo este error: ¡No se puede encontrar el controlador 'ngModel', requerido por la directiva 'select'!
fer
8
ngModel es definitivamente necesario para seleccionar elementos, de acuerdo con la documentación. Las otras directivas son opcionales, pero esa no lo es.
mnemia
26
¡Esto no funciona! ng-change no tiene acceso a la variable temporal (t) creada dentro de ng-options.
Basura
16

también podrías probar esto:

<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>
Dulce vida
fuente
2
Esta solución es buena si necesita formatear el valor. Usando solo el enfoque Seleccionar, no pude formatear el valor fácilmente.
mbokil
7

Si la respuesta de Divyesh Rupawala no funciona (pasando el elemento actual como parámetro), consulte la onChanged()función en este Plunker. Está usando this:

http://plnkr.co/edit/B5TDQJ

abbaf33f
fuente
2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>
Jignesh Variya
fuente
11
Use ng-options en lugar de ng-repeat en una selección.
Jepser Bernardino
12
@JepserBernardino en algún momento necesita un acceso más fino a <opción>, por ejemplo, para diseñar algunas opciones especiales / predeterminadas independientemente de si están seleccionadas o no
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>

Si desea escribir, nombre, id, clase, múltiple, requerido, puede escribir de esta manera.

barış çıracı
fuente
1

Esto podría darte algunas ideas

.NET C # Ver modelo

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

Controlador de API web .NET C #

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);
    }

}

Controlador angular:

$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.");
    }
);

Plantilla angular:

<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>
efecto
fuente
1

Debe usar "seguimiento por" para que los objetos se puedan comparar correctamente. De lo contrario, Angular usará la forma nativa js de comparar objetos.

Entonces su código de ejemplo cambiaría a -

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

El filtro de AngularJS funcionó para mí.

Suponiendo que code/ides único , podemos filtrar ese objeto en particular con AngularJS filtery trabajar con las propiedades de los objetos seleccionados. Considerando el ejemplo anterior:

<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>

Ahora, hay 3 aspectos importantes para esto :

  1. ng-init="search.code = item.size.code"- al inicializar el h1elemento fuera del selectcuadro, establezca la consulta de filtro en la opción seleccionada .

  2. ng-change="update(MAGIC_THING); search.code = item.size.code"- cuando cambie la entrada de selección, ejecutaremos una línea más que establecerá la consulta de "búsqueda" a la seleccionada actualmente item.size.code.

  3. filter:search:true- Pase trueal filtro para permitir una coincidencia estricta .

Eso es. Si size.codees uniqueID , solo tendremos un h1elemento con el texto de size.name.

He probado esto en mi proyecto y funciona.

Buena suerte

Akash
fuente
0

Esta es la forma más limpia de obtener un valor de una lista de opciones de selección angular (que no sea Id o Texto). Suponiendo que tiene un producto seleccionado como este en su página:

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

Luego, en su controlador, configure la función de devolución de llamada de la siguiente manera:

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

Simplemente explicado: dado que el evento ng-change no reconoce los elementos de opción en la selección, estamos utilizando ngModel para filtrar el elemento seleccionado de la lista de opciones cargada en el controlador.

Además, dado que el evento se dispara antes de que el ngModel se actualice realmente, puede obtener resultados no deseados, por lo que una mejor manera sería agregar un tiempo de espera:

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