数据绑定仅在select ng-options中用作语法时才有效

时间:2017-07-06 09:42:45

标签: javascript html angularjs

我从“AngularJS in Action”一书中有以下Angular控制器:

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

以下HTML模板:

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

当我使用这样的代码时,一切正常,如果我想在storyboard.detailsForm中显示我的故事(来自故事板中的故事数组),这将找到并且选择元素将填充来自我选择的卡片的价值。

但是,当我更改select元素中的ng-options时 (使用type.name作为类型...而不是type.name作为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>

然后,填充值不再起作用,并且“请选择”是选择控件中的显示值。我不明白为什么会这样,也无法在书中或网上找到解释。

1 个答案:

答案 0 :(得分:1)

ng-options语法可以理解为value as text for item in items

如果您不使用作为部分(导致text for item in items缺少值部分),那么item本身(对象)将绑定到option(通过以下示例确认),最后为angular选择的空选项无法匹配值绑定到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>