Reputation: 677
I have the following Angular controller from the book AngularJS in Action:
angular.module('Angello.Storyboard')
.controller('StoryboardCtrl', function() {
var storyboard = this;
storyboard.currentStory = null;
storyboard.editedStory = {};
storyboard.setCurrentStory = function(story) {
storyboard.currentStory = story;
storyboard.editedStory = angular.copy(storyboard.currentStory);
};
storyboard.stories = [
{
"assignee": "1",
"criteria": "It tests!",
"description": "This is a test",
"id": "1",
"reporter": "2",
"status": "To Do",
"title": "First Story",
"type": "Spike"
},
{
"assignee": "2",
"criteria": "It works!",
"description": "testing something",
"id": "2",
"reporter": "1",
"status": "Code Review",
"title": "Second Story",
"type": "Enhancement"
}
];
storyboard.types = [
{name: "Spike"},
{name: "Enhancement"}
];
storyboard.users = [
{id: "1", name: "User1"},
{id: "2", name: "User2"}
];
storyboard.statuses = [
{name: 'To Do'},
{name: 'In Progress'},
{name: 'Code Review'},
{name: 'QA Review'},
{name: 'Verified'}
];
});
And the following HTML template:
<div class="list-area">
<div class="list-wrapper">
<ul class="list" ng-repeat="status in storyboard.statuses">
<h3 class="status">{{status.name}}</h3>
<hr/>
<li class="story" ng-repeat="story in storyboard.stories | filter: {status:status.name}" ng-click="storyboard.setCurrentStory(story)">
<article>
<div>
<button type="button" class="close">×</button>
<p class="title">{{story.title}}</p>
</div>
<div class="type-bar {{story.type}}"></div>
<div>
<p>{{story.description}}</p>
</div>
</article>
</li>
</ul>
</div>
</div>
<div class="details">
<h3>Card Details</h3>
<form name="storyboard.detailsForm">
<div class="form-group">
<div class="controls">
<label class="control-label" for="inputTitle">Title</label>
<input type="text" id="inputTitle" name="inputTitle" placeholder="Title"
ng-model="storyboard.editedStory.title" ng-required="true"
ng-minlength="3" ng-maxlength="30" class="form-control">
<label class="control-label" for="inputStatus">Status</label>
<select id="inputStatus" name="inputStatus"
ng-model="storyboard.editedStory.status"
ng-options="status.name as status.name for status in storyboard.statuses"
class="form-control">
<option value="">Please select...</option>
</select>
<label class="control-label" for="inputReporter">Reporter</label>
<select id="inputReporter" name="inputReporter"
ng-model="storyboard.editedStory.reporter" ng-required="true"
ng-options="user.id as user.name for user in storyboard.users"
class="form-control">
<option value="">Please select...</option>
</select>
<label class="control-label" for="inputType">Type</label>
<select id="inputType" name="inputType"
ng-model="storyboard.editedStory.type" ng-required="true"
ng-options="type.name as type.name for type in storyboard.types"
class="form-control">
<option value="" disabled selected>Please select...</option>
</select>
</div>
</div>
</form>
<div ng-if="storyboard.currentStory">
<button class="btn btn-default ng-click="storyboard.updateCancel()">Cancel</button>
<button class="btn pull-right btn-default" ng-disabled="!storyboard.detailsForm.$valid" ng-click="storyboard.updateStory()">Update Story</button>
</div>
</div>
When I using the code like this, all works fine and if I want to display on of my story (from the stories array in the storyboard) in the storyboard.detailsForm, this works find and the select elements are populated with the values from the card that I've selected.
However, when I change the ng-options in the select element like that (use type.name for type ... instead of type.name as type.name for ...):
<select id="inputType" name="inputType"
ng-model="storyboard.editedStory.type" ng-required="true"
ng-options="type.name for type in storyboard.types"
class="form-control">
<option value="" disabled selected>Please select...</option>
</select>
Then, populating the values does not work anymore, and 'Please select' is the displayed value in the select control. I don't understand why this is like that and can't find an explanation neither in the book or online.
Upvotes: 1
Views: 133
Reputation: 38171
ng-options
syntax can be understood as value as text for item in items
.
If you don't use as part(lead to text for item in items
, value part is missing), then item
itself(object) will be bind to option
(confirm by the below example), finally the empty option is setted to be selected for angular can't match any options with the value bind to ng-model
.
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.default1 = 1;
$scope.default2 = 1;
$scope.data = [
{
id: 1,
name: 'name1'
},{
id: 2,
name: 'name2'
},{
id: 3,
name: 'name3'
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<h4>Change options to see what is binded to options</h4>
<select id="inputType" name="inputType"
ng-model="default1" ng-required="true"
ng-options="item.id as item.name for item in data"
class="form-control">
<option value="" disabled selected>Please select...</option>
</select>
{{default1}}<br>
<select id="inputType2" name="inputType2"
ng-model="default2" ng-required="true"
ng-options="item.id for item in data"
class="form-control">
<option value="" disabled selected>Please select...</option>
</select>
{{default2}}
</div>
Upvotes: 1