【问题标题】:Default select not working in ngoptions when model initialized with ng-init使用 ng-init 初始化模型时,默认选择在 ngoptions 中不起作用
【发布时间】:2015-01-12 19:18:10
【问题描述】:

我有一个级联选择,第二个下拉列表基于第一个下拉选择出现​​。出现一个额外的空白选项,这不是下拉菜单预期行为的一部分。

<select ng-init="order.attempt_status_sub = order.attempt_status_sub || subStatuses[0].name" 
    data-ng-model="order.attempt_status_sub" ng-options="subStatus.name as 
    subStatus.name for subStatus in subStatuses"> 
</select>

如何避免空的额外选择出现在下拉列表中?

我的级联下拉菜单的代码是

    <div class="form-group" ng-class="{ 'has-error' : submitted && orderForm.content.$invalid}">
      <div class="controls">
        <select ng-change="getSubStatuses(order.attempt_status)" data-ng-model="order.attempt_status" ng-options="status.name as status.name for status in statuses">
        </select>
      </div>
    </div>

    <div class="form-group" ng-show="subStatuses.length" ng-class="{ 'has-error' : submitted && orderForm.content.$invalid}">
      <div class="controls">
        <select ng-init="order.attempt_status_sub = order.attempt_status_sub || subStatuses[0].name" data-ng-model="order.attempt_status_sub" ng-options="subStatus.name as subStatus.name for subStatus in subStatuses">
        </select>
      </div>
    </div>
$scope.getSubStatuses = function(attempt_status) {

    var statuses = $scope.statuses;
    for(var index in statuses) {
        if(statuses[index].name === attempt_status) {

            if(statuses[index].children) {
                $scope.subStatuses = statuses[index].children;
            } else {
                $scope.subStatuses = [];
            }
            break;
        }
    }
};

【问题讨论】:

  • 您的模型subStatuses 是否异步绑定?
  • @JonathanPalumbo OP 已经在 ng-init 中执行此操作。我不认为它是重复的
  • @PSL 在 subStatuses 异步更改后会再次调用 ng-init 吗?如果没有 plunker,我无法确定,但我猜 ng-init 分配只会运行一次,因此在进行父选择后,子选择的模型仍然无效。我也不能确定。
  • @JonathanPalumbo 不会。 ng-init 不应该用于这些。是的,这是 ng-init 滥用.. :)
  • 是的,在我被咬之前,我一直在滥用它。虽然我认为症状是重复的。原因不同。

标签: javascript angularjs angularjs-scope angularjs-ng-model angularjs-ng-options


【解决方案1】:

我假设您正在为异步绑定数据设置此项。 ng-init 不适合这个目的。拇指规则是不要将ng-init 用于控制器应该做的事情。您应该在控制器中设置视图模型。异步绑定数据时它可能失败的原因是因为未监视 ng-init'ed 表达式。所以它只在第一次渲染期间运行一次,subStatuses 尚未填充,它回退到显示默认的空选项。并且即使在后面的摘要循环期间填充了数据并更新了视图,ng-init 表达式也不会再次运行。

From Doc

ngInit 的唯一适当用途是为 ngRepeat 的特殊属性设置别名,如下面的演示所示。除了这种情况,您应该使用控制器而不是 ngInit 来初始化作用域上的值。

所以只需在控制器中初始化它,而不是使用 ng-init。

$scope.getSubStatuses = function(attempt_status) {

    var statuses = $scope.statuses;
    for(var index in statuses) {
        if(statuses[index].name === attempt_status) {

            if(statuses[index].children) {
                $scope.subStatuses = statuses[index].children;
            } else {
                $scope.subStatuses = [];
            }
            break;
        }
    }
    //Initialize the model here, assuming $scope.order is already initialized
    $scope.order.attempt_status_sub = ($scope.subStatuses[0] ||{}).name;
};

angular.module('app', []).controller('ctrl', function($scope, $timeout) {

  $timeout(function() {
    $scope.subStatuses = [{
      name: 'test1'
    }, {
      name: 'test2'
    }, {
      name: 'test3'
    }];

    $scope.order = {
      attempt_status_sub1: $scope.subStatuses[0].name
    };

  });



});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  With Ng-Init
  <select ng-init="order.attempt_status_sub = order.attempt_status_sub || subStatuses[0].name" data-ng-model="order.attempt_status_sub" ng-options="subStatus.name as 
    subStatus.name for subStatus in subStatuses">
  </select>

  With controller initialization.

  <select data-ng-model="order.attempt_status_sub1" ng-options="subStatus.name as 
    subStatus.name for subStatus in subStatuses">
  </select>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多