Angularjs:更新ng-model时选择不更新

Jho*_*rra 63 javascript angularjs angular-ngmodel

我创建了以下示例,以便您可以准确地看到发生了什么:http: //jsfiddle.net/8t2Ln/101/

如果我使用ng-options,会发生同样的事情.我有一个不同的理由这样做,但为了简化示例留下该部分.

正如您所看到的,它默认有两个选项.我在选择旁边显示ng-model的选定值,这样你就可以看到它是什么.当您使用顶部部分添加第三个选项时,它将值设置为该新选项的值,如选择旁边显示的ng-model值所示,但select本身不会更改以显示正确的值选择.

以下是链接中的示例代码:

var testApp = angular.module('testApp', ['ngRoute']);

testApp.controller('Ctrl', function ($scope) {

    $scope.newInput = '';
    $scope.inputDevice = [
        {
            value: '1',
            label: 'input1'
        },
        {
            value: '2',
            label: 'input2'
        }
    ];
    $scope.selectedDevice = '';

    $scope.addType = function () {
        var newElem = {
            label: $scope.newInput,
            value: '3'
        };
        $scope.inputDevice.push(newElem);
        $scope.selectedDevice = newElem.value;
    };


});
Run Code Online (Sandbox Code Playgroud)

这是html:

<div ng-app="testApp">
    <div ng-controller="Ctrl">
        <p>
            <input type="text" ng-model="newInput" />
            <br />
            <button ng-click="addType()">Add Type</button>
        </p>
        <select ng-model="selectedDevice">
            <option></option>
            <option ng-repeat="i in inputDevice" value="{{ i.value }}">{{ i.label }} - {{ i.value }}</option>
        </select>
        {{ selectedDevice }}</div>
</div>
Run Code Online (Sandbox Code Playgroud)

dfs*_*fsq 95

这正是您不应该使用ngRepeat渲染选择选项的原因.您应该使用ngOptions:

<select ng-model="selectedDevice" 
        ng-options="i.value as (i.label + '-' + i.value) for i in inputDevice">
    <option></option>
</select>
Run Code Online (Sandbox Code Playgroud)

通常,请避免使用ngRepeat渲染选择选项.至少有两个很好的理由.ngRepeat每次迭代创建单独的子范围,在选项标记的情况下不需要.另一个重要的警告是,ngRepeat你只能将select绑定到像字符串这样的基元,但是你无法用它将对象写入ngModel.

这是下面的演示.

angular.module('demo', []).controller('DemoController', function($scope) {

    $scope.newInput = '';
    $scope.inputDevice = [
    	{value: '1', label: 'input1'}, 
        {value: '2', label: 'input2'}
    ];
    
    $scope.selectedDevice = '';
    $scope.addType = function() {
        var newElem = {
            label: $scope.newInput,
            value: Number($scope.inputDevice[$scope.inputDevice.length - 1].value) + 1
        };
        $scope.inputDevice.push(newElem);
        $scope.selectedDevice = newElem.value;
        $scope.newInput = '';
    };

});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<div ng-app="demo" ng-controller="DemoController">
    <form ng-submit="addType()">
        <input type="text" ng-model="newInput" />
        <button type="submit">Add Type</button>
    </form>
    <select ng-model="selectedDevice" ng-options="i.value as (i.label + ' - ' + i.value) for i in inputDevice">
        <option>Select</option>
    </select>
    {{ selectedDevice }}
</div>
Run Code Online (Sandbox Code Playgroud)

  • @BMS空项表示您没有正确设置ngModel,因此Angular不知道选择哪个选项. (2认同)

JME*_*JME 8

问题是,由于您没有使用ng-options浏览器,因此在设置新浏览器时尚未完成渲染selectedDevice.如果您已经开始使用ng-options,则可以使用此解决方法.使用$timeout来包装$scope.selectedDevice = newElem.value;,以确保它运行在浏览器中呈现完毕与变化之后ng-repeat.

我还添加了代码来增加连续添加的下一个值,因为将其硬编码为'3'意味着即使添加了更多的选项,也会连续选择第三个选项.

var testApp = angular.module('testApp', ['ngRoute']);

testApp.controller('Ctrl', function($scope, $timeout) {

  $scope.newInput = '';
  $scope.inputDevice = [{
    value: '1',
    label: 'input1'
  }, {
    value: '2',
    label: 'input2'
  }];
  $scope.selectedDevice = '';

  $scope.addType = function() {
    var last = Number($scope.inputDevice[$scope.inputDevice.length - 1].value) + 1;
    var newElem = {
      label: $scope.newInput,
      value: last.toString()
    };
    $scope.inputDevice.push(newElem);
    $timeout(function() {
      $scope.selectedDevice = newElem.value;
    }, 0);
  };

});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.js"></script>

<div ng-app="testApp">
  <div ng-controller="Ctrl">
    <p>
      <input type="text" ng-model="newInput" />
      <br />
      <button ng-click="addType()">Add Type</button>
    </p>
    <select ng-model="selectedDevice">
      <option></option>
      <option ng-repeat="i in inputDevice" value="{{ i.value }}" ng-selelected="{{ selectedDevice == i.value }}">{{ i.label }} - {{ i.value }}</option>
    </select>
    {{ selectedDevice }}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)