问题
When the model, eyeColorUnknown, contains a value that is not present in the options Angular creates an option with a value of "?" and blank for the visual description as shown below.
<select ng-model="eyeColorUnknown"
ng-options="option.val as (option.desc + ' - ' + option.val) for option in options | orderBy:'desc'"
class="ng-pristine ng-valid">
<option value="?"></option>
<option value="0">Blue - 001</option>
<option value="1">Brown - 003</option>
<option value="2">Green - 002</option>
</select>
Is there a way to either:
1) add an option with a value and a description of "value - description" rather than the ?
For example:
Unknown - 999
Blue - 001
Brown - 003
Green - 002
2) Keep the option but show either a "Uknown" or "val - Unknown"? For example:
<option value="?">Unknown</option>
or
<option value="?">Unknown - 999</option>
<option value="0">Blue - 001</option>
<option value="1">Brown - 003</option>
<option value="2">Green - 002</option>
</select>
3) Others?
Here is a sample code to help re-create the scenario. The $scope.options are currently static, but will be retrieved using a service which can filter an option out of the set when the expiration date is in the past which can cause this situation to occur. I understand there are some discussion that should occur on the SOA side of the house, but was interested in what possibilities are available in the presentation layer.
<html ng-app="sampleApp">
<head lang="en">
<meta charset="utf-8">
<title>HTML Select Demonstration</title>
<link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.2.0/css/bootstrap.css" />
</head>
<body>
<div ng-controller="sampleAppCtrl">
<h1>DEMO of Select and ng-options</h1>
<p></p>
<div>
<select ng-model="eyeColor"
ng-options="option.val as (option.desc + ' - ' + option.val) for option in options | orderBy:'desc'"></select>
<span> Value in the model: [{{eyeColor}}]</span>
</div>
<div>
<select ng-model="eyeColorUnknown"
ng-options="option.val as (option.desc + ' - ' + option.val) for option in options | orderBy:'desc'"></select>
<span> Value in the model: [{{eyeColorUnknown}}]</span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<script type="text/javascript" src="sample_app.js"></script>
</body>
</html>
sample.js
var app = angular.module('sampleApp', []);
(function()
{
angular.module('sampleApp').controller('sampleAppCtrl', SampleAppController);
function SampleAppController($scope)
{
$scope.eyeColor = "001";
$scope.eyeColorUnknown = "999";
$scope.options = [ {
"val": "001",
"desc": "Blue"
}, {
"val": "002",
"desc": "Green"
}, {
"val": "003",
"desc": "Brown"
} ];
}
;
})();
UPDATE 2015-02-13: The selectDirective provided in angular.js contains a render() method that inserts a '' when the model value doesn't match a value in the options. The angular code excerpt is shown below modified to shown Unknown instead of nothing. I'm looking for suggestions without having to modify the angular.js code. I hope this clarifies my challenge.
if (!multiple) {
if (nullOption || modelValue === null) {
// insert null option if we have a placeholder, or the model is null
optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
} else if (!selectedSet) {
// option could not be found, we have to insert the undefined item
//
// WARNING: Modified to show 'Unknown' rather than nothing.
//
optionGroups[''].unshift({id:'?', label:'Unknown', selected:true});
}
}
Any assistance would be much appreciated.
回答1:
Based on your replies to comments on your question, you want the default option "Unknown - 999" to be added in addition to dynamically retrieved options.
There are 2 ways to do this.
Alternative 1:
If it is critical to satisfy the requirement that option "Unknown - 999" should have value of "999"
, then you can add this option to the dynamically retrieved options:
$http.get("service/eyeColors").then(function(result){
$scope.options = result.data;
$scope.options.unshift({val: "999", desc: "Unknown"});
});
And just use ng-options
as usual:
<select ng-model="eyeColor"
ng-options="o.val as (o.desc + ' - ' + o.val) for 0 in options">
</select>
The problem here is that if $scope.eyeColor
equals a value that does not exist in the list or undefined
, then <select>
will add a blank option, but it will not use the "Unknown - 999" as the default.
Another potential problem is that Unknown - 999
would be sorted together with other options, and would not be first in line.
Alternative 2:
Add a default option of "Unknown - 999" statically, as per Angular's documentation on <select>
:
Optionally, a single hard-coded element, with the value set to an empty string, can be nested into the element. This element will then represent the null or "not selected" option. See example below for demonstration.
<select ng-model="eyeColor"
ng-options="o.val as (o.desc + ' - ' + o.val) for 0 in options">
<option value="">Unknown - 999</option>
</select>
The problem here is that the default "Unknown - 999" option will set the model to null
and not to "999"
, but the benefit is that any invalid (or not yet set) value of the model would automatically show "Unknown - 999". You can change null
to "999"
when you need to save the value to the backend.
plunker
回答2:
I'm doing something a bit similar, I think. I'm using this data structure:
"choices": [
{ "name": "-- Select an item --", "value": "" },
{ "name": "1 - text", "value": "1" },
{ "name": "2 - text", "value": "2" },
{ "name": "3 - text", "value": "3" },
{ "name": "4 - text", "value": "4" },
{ "name": "Other", "value": "_ANY_" }
]
"Select an item" will show when there is no option selected. "Other" will show when the value is something other than null or "". If "other" is selected, a text input appears(when that input is "dirty," a submit button appears).
The way I did it is to create a dummy data field that I calculate on the fly. When a user clicks on "other," I set the input field to visible and disable the data submit to the server. I couldn't figure out an override to angular setting an item that's not in the select list to blank. My solution is tied into a number of other processes - I don't have a clear boiled down example. Let me know if you want more info on this.
来源:https://stackoverflow.com/questions/28373770/angular-ng-options-is-there-a-way-to-add-an-option-when-the-model-contains-a-v