javascript - ejemplos - ng-bind-html angularjs
¿Cómo establezco la propiedad de valor en las opciones ng de AngularJS? (27)
Ver ngOptions
ngOptions (opcional) - {
comprehension_expression=
} - en una de las 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 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 objeto: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 atributo de value
del elemento select
con track by
expresión.
<select ng-options="obj.text for obj in array track by obj.value">
</select>
Como recordar estas cosas feas.
Para todas las personas que están teniendo dificultades para recordar esta forma de sintaxis: Estoy de acuerdo en que esta no es la sintaxis más fácil o hermosa. Esta sintaxis es una especie de versión extendida de las listas de comprensión de Python y saber que me ayuda a recordar la sintaxis con mucha facilidad. Es algo como esto:
Código 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 que se mencionó anteriormente. Sin embargo, en <select>
normalmente necesitamos diferenciar entre el valor real en el código y el texto mostrado (la etiqueta) en un elemento <select>
.
Como, necesitamos person.id
en el código, pero no queremos mostrar el id
al usuario; Queremos mostrar su nombre. Del mismo modo, no estamos interesados en la person.name
en el código. Ahí viene la palabra clave as
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 la person
instancia / referencia en sí. Vea abajo:
person as person.name for person in people
Para objetos de JavaScript, el mismo método se aplica también. Solo recuerde que los elementos en el objeto están deconstruidos con pares (key, value)
.
Esto es lo que parece estar molestando a mucha gente (incluyéndome a mí).
Al usar la directiva ng-options
en AngularJS para completar las opciones para una etiqueta <select>
, no puedo averiguar cómo establecer el valor para una opción. La documentación para esto no está muy clara, al menos para un simplón 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 no lo entiendo.
directiva ngOptions:
$scope.items = [{name: ''a'', age: 20},{ name: ''b'', age: 30},{ name: ''c'', age: 40}];
Caso-1) etiqueta para el valor en la matriz:
<div> <p>selected item is : {{selectedItem}}</p> <p> age of selected item is : {{selectedItem.age}} </p> <select ng-model="selectedItem" ng-options="item.name for item in items"> </select> </div>
Explicación de salida (Asume el primer elemento seleccionado):
selectedItem = {name: ''a'', age: 20} // [de forma predeterminada, el elemento seleccionado es igual al elemento de valor ]
selectedItem.age = 20
Caso 2) seleccione como etiqueta para el valor en la matriz:
<div> <p>selected item is : {{selectedItem}}</p> <select ng-model="selectedItem" ng-options="item.age as item.name for item in items"> </select> </div>
Explicación de salida (suponga el primer elemento seleccionado): selectedItem = 20 // [seleccionar part is item.age ]
Aquí es cómo resuelvo este problema en una aplicación heredada:
En HTML:
ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"
En JavaScript:
vm.kitTypes = [
{"id": "1", "name": "Virtual"},
{"id": "2", "name": "Physical"},
{"id": "3", "name": "Hybrid"}
];
...
vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
return value.id === (vm.itemTypeId || 1);
})[0];
Mi HTML muestra el valor de la opción correctamente.
Así es como resolví esto. Realicé un seguimiento de la selección por valor y configuré la propiedad del elemento seleccionado al 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 límite de país correcto.
Cómo los atributos de valor obtienen su valor:
- Cuando se usa 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.
Así que en tu caso debería ser:
obj = { ''1'': ''1st'', ''2'': ''2nd'' };
<select ng-options="k as v for (k,v) in obj"></select>
Como muchos han dicho antes, si tengo datos algo como esto:
countries : [
{
"key": 1,
"name": "UAE"
},
{
"key": 2,
"name": "India"
},
{
"key": 3,
"name": "OMAN"
}
]
Yo lo usaría como:
<select
ng-model="selectedCountry"
ng-options="obj.name for obj in countries">
</select>
En su Controlador debe establecer un valor inicial para deshacerse del primer elemento vacío:
$scope.selectedCountry = $scope.countries[0];
// You need to watch changes to get selected value
$scope.$watchCollection(function() {
return $scope.selectedCountry
}, function(newVal, oldVal) {
if (newVal === oldVal) {
console.log("nothing has changed " + $scope.selectedCountry)
}
else {
console.log(''new value '' + $scope.selectedCountry)
}
}, true)
Ejecute el fragmento de código y vea las variaciones. Aquí hay una nota para una rápida comprensión.
Ejemplo 1 (Selección de objeto): -
ng-option="os.name for os in osList track by os.id"
. Aquí eltrack by os.id
es importante y debería estar allí yos.id as
NO debe tener antes deos.name
.- El
ng-model="my_os"
debe establecerse en un objeto con la clave id comomy_os={id: 2}
.
- El
Ejemplo 2 (Selección de valor): -
ng-option="os.id as os.name for os in osList"
. Aquí eltrack by os.id
NO debería estar allí yos.id as
debería estar allí antes deos.name
.- El
ng-model="my_os"
debe establecerse en un valor comomy_os= 2
- El
El fragmento de código de descanso lo explicará.
angular.module(''app'', []).controller(''ctrl'', function($scope, $timeout){
//************ EXAMPLE 1 *******************
$scope.osList =[
{ id: 1, name :''iOS''},
{ id: 2, name :''Android''},
{ id: 3, name :''Windows''}
]
$scope.my_os = {id: 2};
//************ EXAMPLE 2 *******************
$timeout(function(){
$scope.siteList = [
{ id: 1, name: ''Google''},
{ id: 2, name: ''Yahoo''},
{ id: 3, name: ''Bing''}
];
}, 1000);
$scope.my_site = 2;
$timeout(function(){
$scope.my_site = 3;
}, 2000);
})
fieldset{
margin-bottom: 40px;
}
strong{
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.10/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<!--//************ EXAMPLE 1 *******************-->
<fieldset>
<legend>Example 1 (Set selection as <strong>object</strong>)</legend>
<select ng-model="my_os" ng-options="os.name for os in osList track by os.id">
<option value="">--Select--</option>
</select>
{{my_os}}
</fieldset>
<!--//************ EXAMPLE 2 *******************-->
<fieldset>
<legend>Example 2 (Set selection as <strong>value</strong>. Simulate ajax)</legend>
<select ng-model="my_site" ng-options="site.id as site.name for site in siteList">
<option value="">--Select--</option>
</select>
{{my_site}}
</fieldset>
</div>
El usuario frm.adiputra proporcionó la respuesta correcta a esta pregunta, ya que actualmente parece ser la única manera de controlar explícitamente el atributo de valor de los elementos de opción.
Sin embargo, solo quería enfatizar que "seleccionar" no es una palabra clave en este contexto, sino que es solo un marcador de posición para una expresión. Consulte la siguiente lista, para la definición de la expresión "seleccionar", así como otras expresiones que se pueden usar en la directiva ng-options.
El uso de seleccionar como se muestra en la pregunta:
ng-options=''select p.text for p in resultOptions''
es esencialmente incorrecto
Según la lista de expresiones, parece que trackexpr puede usarse para especificar el valor, cuando las opciones se dan en una matriz de objetos, pero se ha usado solo con agrupación.
De la documentación de AngularJS para ng-options:
- matriz / objeto : una expresión que se evalúa como una matriz / objeto para iterar sobre.
- valor : variable local que se referirá a cada elemento de la matriz o al valor de cada propiedad del objeto durante la iteración.
- clave : variable local que hará referencia al nombre de una propiedad en el objeto durante la iteración.
- etiqueta : El resultado de esta expresión será la etiqueta para el elemento. La expresión probablemente se referirá a la variable de valor (por ejemplo, value.propertyName).
- seleccionar : el resultado de esta expresión se vinculará al modelo del elemento principal. Si no se especifica, seleccione la expresión por defecto a valor.
- grupo : el resultado de esta expresión se usará para agrupar opciones usando el elemento DOM.
- trackexpr : se utiliza cuando se trabaja con una matriz de objetos. El resultado de esta expresión se utilizará para identificar los objetos en la matriz. El trackexpr probablemente se referirá a la variable de valor (por ejemplo, value.propertyName).
El tutorial ANGULAR.JS: NG-SELECT Y NG-OPTIONS me ayudó a resolver el problema:
<select id="countryId"
class="form-control"
data-ng-model="entity.countryId"
ng-options="value.dataValue as value.dataText group by value.group for value in countries"></select>
En lugar de utilizar la nueva función "seguimiento 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>
Note la diferencia entre la sintaxis estándar, que hará que los valores sean las claves del Objeto / Array, 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 en v como v .
Descubrí esto solo basado en el sentido común mirando la sintaxis. (k, v) es la declaración real que divide la matriz / objeto en pares de valores clave.
En la declaración ''k como v'', k será el valor yv será la opción de texto que se muestra al usuario. Creo que ''seguimiento por'' es desordenado y excesivo.
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 enlazar los datos. Obtendrá el valor que contendrá el objeto y la selección predeterminada según su escenario.
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 llevan. Todos me ayudaron a asimilar 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í, 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>
Note que no usé la track by
. El uso de la track by
el elemento seleccionado siempre devolverá el objeto que coincide con el ID de Firmness, en lugar del ID de Firmness en sí. Ahora cumple con mis criterios, que es que debe devolver un valor numérico en lugar del objeto, y usar ng-options
para obtener la mejora de rendimiento que proporciona al no crear un nuevo ámbito para cada opción generada.
Además, necesitaba la primera fila en blanco, así que simplemente agregué una <option>
al elemento <select>
.
Aquí hay un Plunkr que muestra mi trabajo.
La directiva ng-options
no establece el atributo de valor en los elementos <options>
para matrices:
Usar limit.value as limit.text for limit in limits
significa:
establecer la etiqueta de la
<option>
comolimit.text
guarde el valor de valorlimit.value
en elng-model
la selección
Ver la pregunta de Desbordamiento de pila AngularJS ng-options no valores de representación .
La selección de un elemento en ng-options puede ser un poco difícil dependiendo de cómo configure la fuente de datos.
Después de luchar con ellos por un tiempo, terminé haciendo una muestra con las fuentes de datos más comunes que uso. Lo puedes encontrar aquí:
http://plnkr.co/edit/fGq2PM?p=preview
Ahora para hacer que ng-options funcione, aquí hay algunas cosas a considerar:
- Normalmente, obtiene las opciones de una fuente y el valor seleccionado de otra. Por ejemplo:
- estados :: datos para ng-opciones
- user.state :: Opción para establecer como seleccionado
- Basado en 1, lo más fácil / lógico es rellenar la selección con una fuente y luego establecer el valor a través del código seleccionado. Rara vez sería mejor obtener un conjunto de datos mixtos.
- AngularJS permite que los controles de selección contengan más de una
key | label
key | label
Muchos ejemplos en línea ponen los objetos como ''clave'', y si necesita información del objeto configurado de esa manera, use la propiedad específica que necesita como clave. (ID, CODIGO, etc. Como en la muestra plckr) La forma de establecer el valor del control desplegable / de selección depende de # 3,
- Si la clave desplegable es una propiedad única (como en todos los ejemplos en el plunkr), simplemente la establece, por ejemplo:
$scope.dropdownmodel = $scope.user.state;
Si configura el objeto como clave, debe recorrer las opciones, incluso si asigna el objeto no configurará el elemento como seleccionado, ya que tendrán diferentes hashkeys, por ejemplo:
for (var i = 0, len = $scope.options.length; i < len; i++) { if ($scope.options[i].id == savedValue) { // Your own property here: console.log(''Found target! ''); $scope.value = $scope.options[i]; break; } }
- Si la clave desplegable es una propiedad única (como en todos los ejemplos en el plunkr), simplemente la establece, por ejemplo:
Puede reemplazar savedValue para la misma propiedad en el otro objeto, $scope.myObject.myProperty
.
Para enviar un valor personalizado llamado my_hero
al servidor mediante un formulario normal, envíe:
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á iron
o super
como el valor de my_hero
.
Esto es similar a la respuesta de @neemzy , pero especificando datos separados para el atributo de value
.
Para mí la respuesta de Bruno Gomes es la mejor respuesta.
Pero en realidad, no debe preocuparse por establecer la propiedad de valor de las opciones seleccionadas. AngularJS se encargará de eso. Déjame explicarte en detalle.
Por favor considera este violín
angular.module(''mySettings'', []).controller(''appSettingsCtrl'', function ($scope) {
$scope.timeFormatTemplates = [{
label: "Seconds",
value: ''ss''
}, {
label: "Minutes",
value: ''mm''
}, {
label: "Hours",
value: ''hh''
}];
$scope.inactivity_settings = {
status: false,
inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
//time_format: ''ss'', // Second (default value)
time_format: $scope.timeFormatTemplates[0], // Default seconds object
};
$scope.activity_settings = {
status: false,
active_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
//time_format: ''ss'', // Second (default value)
time_format: $scope.timeFormatTemplates[0], // Default seconds object
};
$scope.changedTimeFormat = function (time_format) {
''use strict'';
console.log(''time changed'');
console.log(time_format);
var newValue = time_format.value;
// do your update settings stuffs
}
});
Como puede ver en la salida de violín, independientemente de lo que elija para las opciones del cuadro de selección, es su valor personalizado o el valor generado automáticamente de 0, 1, 2 por AngularJS, no importa en su salida a menos que esté utilizando jQuery o cualquiera otra biblioteca para acceder al valor de las opciones del cuadro combinado de selección y manipularlo en consecuencia.
Para un objeto:
<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select>
Puede usar ng-options para lograr un enlace de etiqueta seleccionado para valorar y mostrar miembros
Durante el uso de esta fuente de datos
countries : [
{
"key": 1,
"name": "UAE"
},
{
"key": 2,
"name": "India"
},
{
"key": 3,
"name": "OMAN"
}
]
puede usar lo siguiente para enlazar su etiqueta de selección a valor y nombre
<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>
funciona muy bien
Puedes hacerlo:
<select ng-model="model">
<option value="">Select</option>
<option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>
- ACTUALIZACIÓN
Después de algunas actualizaciones, la solución del usuario frm.adiputra es mucho mejor. Código:
obj = { ''1'': ''1st'', ''2'': ''2nd'' };
<select ng-options="k as v for (k,v) in obj"></select>
Si desea cambiar el valor de los elementos de su option
porque el formulario finalmente se enviará 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.
Siempre es doloroso para los desarrolladores con ng-options. Por ejemplo: obtener un valor vacío / en blanco seleccionado en la etiqueta de selección. Especialmente cuando se trata de objetos JSON en ng-options, se vuelve más tedioso. Aquí he hecho algunos ejercicios sobre eso.
Objetivo: Iterar la matriz de objetos JSON a través de la opción ng y configurar el primer elemento seleccionado.
Datos:
someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]
En la etiqueta de selección tuve que mostrar xyz y abc, donde xyz debe seleccionarse sin mucho esfuerzo.
HTML:
<pre class="default prettyprint prettyprinted" style=""><code>
<select class="form-control" name="test" style="width:160px" ng-options="name.someName for name in someNames" ng-model="testModel.test" ng-selected = "testModel.test = testModel.test || someNames[0]">
</select>
</code></pre>
Por ejemplo de código anterior, puede salir de esta exageración.
Otra reference :
Un año después de la pregunta, tuve que encontrar una respuesta para esta pregunta, ya que ninguna de ellas me dio la respuesta real, al menos para mí.
Usted ha preguntado cómo seleccionar la opción, pero nadie ha dicho que estas dos cosas NO son las mismas:
Si tenemos opciones como esta:
$scope.options = [
{ label: ''one'', value: 1 },
{ label: ''two'', value: 2 }
];
Y tratamos de establecer una opción predeterminada como esta:
$scope.incorrectlySelected = { label: ''two'', value: 2 };
NO funcionará, pero si intentas seleccionar la opción como esta:
$scope.correctlySelected = $scope.options[1];
Funcionará.
Aunque estos dos objetos tienen las mismas propiedades, AngularJS los considera DIFERENTES porque AngularJS se compara con la referencia .
Eche un vistazo al violín http://jsfiddle.net/qWzTb/ .
Utilice la pista por propiedad que diferencia valores y etiquetas en el cuadro de selección.
Por favor, inténtalo
<select ng-options="obj.text for obj in array track by obj.value"></select>
que asignará etiquetas con texto y valor con valor (de la matriz)
Yo también tuve este problema. 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 opciones de ng:
HTML:
<select ng-options="room.name for room in Rooms track by room.price">
<option value="">--Rooms--</option>
</select>
Utilizo "track by" para establecer 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 valores diferentes.)
JSON:
$scope.Rooms = [
{ name: ''SALA01'', price: 100 },
{ name: ''SALA02'', price: 200 },
{ name: ''SALA03'', price: 300 }
];
Lo aprendí de la publicación del blog Cómo establecer el valor seleccionado inicial de un elemento seleccionado usando Angular.JS ng-options & track by .
Ver el vídeo. Es una buena clase :)
Parece que ng-options
son complicadas (posiblemente frustrantes) de usar, pero en realidad tenemos un problema de arquitectura.
AngularJS sirve como marco MVC para una aplicación dinámica de HTML + JavaScript. Si bien su componente (V) iew ofrece "plantillas" HTML, su propósito principal es conectar las acciones del usuario, a través de un controlador, a 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 en un valor de una consulta .
- La forma en que se presenta una fila de consulta al usuario es la preocupación de la (V) iew y
ng-options
proporciona la palabra clavefor
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 una fila seleccionada se presenta al servidor es la preocupación de (M) odel. Por lo tanto,
ng-options
proporciona la palabra claveas
para especificar qué valor se proporciona al modelo como enk as v for (k,v) in objects
.
La solución correcta es que el problema es de naturaleza arquitectónica e implica refactorizar su HTML para que el odel (M) realice la comunicación con el servidor cuando sea necesario (en lugar de que el usuario envíe un formulario).
Si una página HTML de MVC no es necesaria para realizar una ingeniería excesiva para el problema en cuestión: entonces use solo la parte de generación HTML del componente de vista de AngularJS (V). En este caso, siga el mismo patrón que se usa para generar elementos como <li />
está debajo de <ul />
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}}” />
<select ng-model="color" ng-options="(c.name+'' ''+c.shade) for c in colors"></select><br>
<select ng-model="output">
<option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
</select>