AngularJS选择器的值未定义。

7

现在我正在尝试从下拉选择框中获取值,但它返回 undefined。问题是在 html 级别上它按照预期工作,以下是我的代码:

<div class='subcontent'>            
  <input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y"><label for="me" class='choosemethod'>Me</label>
  <input id="company" type="radio"  ng-model="paymentmethod" value="N" class='choosemethod'><label for="company" class='choosemethod'>My Company</label><br/>
  <span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>

<div class='paymentmethods subcontent' ng-switch on="paymentmethod">
  <select ng-model='selectedmethod' ng-init="selectedmethod=Memethods[0]" id='methods' ng-switch-when='Y'>
    <option ng-repeat="method in Memethods" value="{{method}}">{{method}}</option>
  </select>

  <select ng-model='selectedmethod' ng-init="selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
    <option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
  </select>

  <div class='clear'></div>
  <label for ='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>

在js中:
$scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
$scope.companies = ['Company Paid','MyAMEX'];

页面上显示正常,但在获取值时显示为未定义。有什么想法?

1
你是否了解使用ng-options指令设置选择选项?那么你就不必自己生成选项标签,而且它还有其他优点。一旦你尝试过,就会发现比你想象的更容易。文档可以比我更好地解释它: https://docs.angularjs.org/api/ng/directive/ngOptions - Surreal Dreams
3个回答

10

这是经典的"Angular点符号"问题。

这里有一个有效的示例

基本上,ng-switch创建了一个新的作用域,所以当选择设置selectedmethod属性时,它是在新的作用域中进行的,而不是在控制器作用域中进行,这是您所期望的。一个解决方案是为您的模型创建一个父对象。

angular.module('app',[])
.controller('main', function($scope){
  $scope.selection = {};
  $scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
  $scope.companies = ['Company Paid','MyAMEX'];
})

注意它在 HTML 中的引用方式不同:

<select ng-model='selection.selectedmethod' ng-init="selection.selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
  <option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
</select>

一种不同(或许更好)的方法是使用"ControllerAs"语法,它可以自动完成这个过程。

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

      this.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
      this.companies = ['Company Paid','MyAMEX'];
    })

<body ng-app="app" ng-controller="main as main">
  <div class='subcontent'>
    <input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y">
    <label for="me" class='choosemethod'>Me</label>
    <input id="company" type="radio" ng-model="paymentmethod" value="N" class='choosemethod'>
    <label for="company" class='choosemethod'>My Company</label>
    <br/>
    <span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
  </div>

  <div class='paymentmethods subcontent' ng-switch on="paymentmethod">
    <select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.Memethods[0]" id='methods' ng-switch-when='Y'>
      <option ng-repeat="method in main.Memethods" value="{{method}}">{{method}}</option>
    </select>

    <select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.companies[0]" ng-switch-when='N' style='float:left'>
      <option ng-repeat='companyoption in main.companies' value="{{companyoption}}">{{companyoption}}</option>
    </select>

    <div class='clear'></div>
    <label for='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>

  </div>
  <div>{{main.selectedmethod}}</div>
</body>

这就是我所需要的,我认为可能是作用域的问题,但是不知道出在哪里和为什么。谢谢! - linyuanxie
解释得很清楚,尽管我认为你对于“controller as”语法的代码示例并不完全正确 - 难道你不需要将其余的引用Memethodscompanies改为main.Memethods/main.companies吗?控制器实例的所有属性只能通过作用域属性在作用域上访问,而在这种情况下,作用域属性是“main”。 - GregL
这就是我在iPad上回答问题的结果。已编辑。谢谢。 - Joe Enzminger

1

在值中内部的ng-model必须在表示之前进行初始化。因此,ng-init出现在ng-model之前。在选项中,$first用于选择第一个值。

<select ng-init= "selectedmethod=companies[0]" ng-model='selectedmethod' ng-switch-when='N' style='float:left'>
    <option ng-repeat='companyoption in companies' value="{{companyoption}}" ng-selected="$first">{{companyoption}} 
    </option>
</select>

1

您可以参考这个简单的示例

HTML代码:

<div ng-controller="Main" ng-app>
    <div>selections = {{selections}}</div>

    <div>
      <p>Model doesn't get updated when selecting:</p>
      <select ng-repeat="selection in selections" ng-model="selection" ng-options="i.id as i.name for i in items">
        <option value=""></option>
      </select>
    </div>

js代码:

function Main($scope) {

    $scope.selections = ["", "id-2", ""];

    $scope.reset = function() {
        $scope.selections = ["", "", ""];
    };

    $scope.sample = function() {
        $scope.selections = [ "id-1", "id-2", "id-3" ];
    }

    $scope.items = [{
        id: 'id-1',
        name: 'Name 1'},
    {
        id: 'id-2',
        name: 'Name 2'},
    {
        id: 'id-3',
        name: 'Name 3'}];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接