Pregunta ¿Cómo configuro la propiedad value en AngularJS 'ng-options?


Esto es lo que parece molestar a mucha gente (incluyéndome a mí).

Al usar el ng-options directiva en AngularJS para completar las opciones de un <select> etiqueta, no puedo entender cómo establecer el valor de una opción. La documentación para esto no está clara, al menos para un tonto como yo.

Puedo configurar el texto para una opción fácilmente así:

ng-options="select p.text for p in resultOptions"

Cuando resultOptions es por ejemplo:

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

Debería ser (y probablemente sea) lo más simple para establecer los valores de las opciones, pero hasta ahora simplemente no lo entiendo.


527
2017-08-27 09:13


origen


Respuestas:


Ver ngOptions

ngOptions (opcional) - {comprehension_expression=} - en uno de los   siguientes formas:

Para fuentes de datos de matriz:    label for value in array select as label for value in array label group by group for value in array select as label group by group for value in array track by trackexpr Para fuentes de datos de objetos: label for (key , value) in object select as label for (key , value) in object label group by group for (key, value) in object select as label group by group for (key, value) in object

En tu caso, debería ser

array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];

<select ng-options="obj.value as obj.text for obj in array"></select>

Actualizar

Con las actualizaciones en AngularJS, ahora es posible establecer el valor real para el value atributo de select elemento con track by expresión.

<select ng-options="obj.text for obj in array track by obj.value">
</select>

Cómo recordar estas cosas feas

Para todas las personas que están teniendo dificultades para recordar esta forma de sintaxis: acepto que esta no es la sintaxis más fácil o bella. Esta sintaxis es una especie de versión extendida de las listas de comprensión y conocimiento de Python que me ayuda a recordar la sintaxis con mucha facilidad. Es algo como esto:

Código de Python:

my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]

# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']

Esta es en realidad la misma sintaxis que la primera enumerada anteriormente. Sin embargo, en <select> usualmente necesitamos diferenciar entre el valor real en el código y el texto mostrado (la etiqueta) en un <select> elemento.

Como, necesitamos person.id en el código, pero no queremos mostrar el id para el usuario; queremos mostrar su nombre Del mismo modo, no estamos interesados ​​en el person.name en el código. Ahí viene el as palabra clave para etiquetar cosas Entonces se vuelve así:

person.id as person.name for person in people

O, en lugar de person.id podríamos necesitar el person instancia / referencia en sí. Vea abajo:

person as person.name for person in people

Para los objetos de JavaScript, también se aplica el mismo método. Solo recuerde que los elementos en el objeto se deconstruyen con (key, value) pares.


663
2017-08-27 10:33



Cómo los atributos de valor obtienen su valor:

  • Cuando se utiliza una matriz como fuente de datos, será el índice del elemento de la matriz en cada iteración;
  • Al usar un objeto como fuente de datos, será el nombre de la propiedad en cada iteración.

Entonces en tu caso debería ser:

obj = { '1': '1st', '2': '2nd' };

<select ng-options="k as v for (k,v) in obj"></select>

129
2017-09-12 08:44



Tuve este problema también. No pude establecer mi valor en ng-options. Cada opción que se generó se configuró con 0, 1, ..., n.

Para hacerlo bien, hice algo como esto en mis ng-options:

HTML:

<select ng-options="room.name for room in Rooms track by room.price">
    <option value="">--Rooms--</option>
</select>

Uso "track by" para configurar todos mis valores con room.price.

(Este ejemplo apesta: porque si hubiera más de un precio igual, el código fallaría. ASEGÚRESE de tener diferentes valores).

JSON:

$scope.Rooms = [
            { name: 'SALA01', price: 100 },
            { name: 'SALA02', price: 200 },
            { name: 'SALA03', price: 300 }
        ];

Lo aprendí de una publicación de blog Cómo establecer el valor inicial seleccionado de un elemento seleccionado usando Angular.JS ng-options & track by.

Ver el vídeo. Es una buena clase :)


116
2018-04-10 19:17



Si quieres cambiar el valor de tu optionelementos porque el formulario se enviará finalmente al servidor, en lugar de hacerlo,

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

Puedes hacerlo:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

El valor esperado se enviará a través del formulario con el nombre correcto.


46
2018-06-12 16:35



Para enviar un valor personalizado llamado my_hero al servidor usando un envío de formulario normal:

JSON:

"heroes": [
  {"id":"iron", "label":"Iron Man Rocks!"},
  {"id":"super", "label":"Superman Rocks!"}
]

HTML:

<select ng-model="hero" ng-options="obj.id as obj.label for obj in heroes"></select>
<input type="hidden" name="my_hero" value="{{hero}}" />

El servidor recibirá cualquiera iron o super como el valor de my_hero.

Esto es similar a la respuesta por @neemzy, pero especificando datos separados para value atributo.


25
2017-11-28 19:00



Parece que ng-options es complicado (posiblemente frustrante) de usar, pero en realidad tenemos un problema de arquitectura.

AngularJS sirve como un marco MVC para una aplicación dinámica HTML + JavaScript. Si bien su componente (V) iew ofrece "plantillas" de HTML, su objetivo principal es conectar las acciones del usuario, a través de un controlador, con los cambios en el modelo. Por lo tanto el nivel apropiado de abstracción, desde el cual trabajar en AngularJS, es que un elemento seleccionado establece un valor en el modelo a un valor de una consulta.

  • Cómo se presenta una fila de consulta al usuario es la preocupación de (V) iew ng-options proporciona el for palabra clave para dictar cuál debe ser el contenido del elemento de opción es decir  p.text for p in resultOptions.
  • La forma en que se presenta una fila seleccionada al servidor es la preocupación del (M) odel. Por lo tanto ng-options proporciona el as palabra clave para especificar qué valor se proporciona al modelo como en k as v for (k,v) in objects.

La solución correcta, este es un problema de naturaleza arquitectónica e implica la refacturación de su HTML para que el odel (M) realice la comunicación del servidor cuando sea necesario. (en lugar de que el usuario envíe un formulario).

Si una página HTML de MVC es una sobreingeniería innecesaria para el problema en cuestión: luego use solo la porción de generación de HTML del componente AngularJS (V) iew. En este caso, siga el mismo patrón que se utiliza para generar elementos tales como &lt;li /&gt;debajo &lt;ul /&gt;y coloque una repetición ng en un elemento de opción:

<select name=“value”>
    <option ng-repeat=“value in Model.Values” value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

Como kludge, siempre se puede mover el atributo de nombre del elemento de selección a un elemento de entrada oculto:

<select ng-model=“selectedValue” ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden” name=“value” value=“{{selectedValue}}” />

23
2017-11-16 23:06



Puedes hacerlo:

<select ng-model="model">
    <option value="">Select</option>
    <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>

- ACTUALIZAR

Después de algunas actualizaciones, usuario frm.adiputrala solución es mucho mejor. Código:

obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>

19
2017-11-01 19:00



He luchado con este problema por un tiempo hoy. Leí la documentación de AngularJS, esta y otras publicaciones y algunos de los blogs a los que conducen. Todos me ayudaron a descifrar los detalles más finos, pero al final esto parece ser un tema confuso. Principalmente debido a los muchos matices sintácticos de ng-options.

Al final, para mí, todo se redujo a menos es más.

Dado un alcance configurado de la siguiente manera:

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

Esto es todo lo que necesitaba para obtener el resultado deseado:

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

Aviso que no usé track by. Utilizando track by el ítem seleccionado siempre devolvería el objeto que coincidía con el FirmnessID, en lugar de con el FirmnessID. Esto ahora cumple mis criterios, que es que debe devolver un valor numérico en lugar del objeto, y usar ng-options para obtener la mejora del rendimiento que proporciona al no crear un nuevo alcance para cada opción generada.

Además, necesitaba la primera fila en blanco, así que simplemente agregué un <option> al <select> elemento.

Aquí hay un Plunkr eso muestra mi trabajo.


13
2018-05-17 20:04



En lugar de utilizar la nueva función 'rastrear por', simplemente puede hacer esto con una matriz si desea que los valores sean los mismos que el texto:

<select ng-options="v as v for (k,v) in Array/Obj"></select>

Tenga en cuenta la diferencia entre la sintaxis estándar, que convertirá los valores en las claves del objeto / matriz, y por lo tanto, 0,1,2, etc. para una matriz:

<select ng-options"k as v for (k,v) in Array/Obj"></select>

k como v se convierte v como v.

Descubrí esto simplemente basado en el sentido común mirando la sintaxis. (k, v) es la declaración real que divide el conjunto / objeto en pares de valores clave.

En la declaración 'k as v', k será el valor, y v será la opción de texto que se mostrará al usuario. Creo que 'seguir por' es desordenado y excesivo.


10
2017-08-20 12:23



Esto fue más adecuado para todos los escenarios de acuerdo a mí:

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

donde puedes usar tu modelo para vincular los datos. Obtendrá el valor que contendrá el objeto y la selección predeterminada en función de su escenario.


9
2018-06-04 13:22



Así es como resolví esto. Seguí la selección por valor y establecí la propiedad del elemento seleccionado para el modelo en mi código JavaScript.

Countries =
[
    {
        CountryId = 1, Code = 'USA', CountryName = 'United States of America'
    },
    {
       CountryId = 2, Code = 'CAN', CountryName = 'Canada'
    }
]
<select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId">

vm es mi controlador y el país en el controlador recuperado del servicio es {CountryId =1, Code = 'USA', CountryName='United States of America'}.

Cuando seleccioné otro país del menú desplegable de selección y publiqué mi página con "Guardar", obtuve el país correcto.


8
2017-09-25 19:52