选择标记中ng-model的问题

时间:2015-11-04 10:04:35

标签: javascript angularjs

我有一个select元素,我尝试检索使用ng-model选择的值。它正确地显示在我的应用程序页面上,但在app控制器中它仍然是初始值。我一直在网上寻找答案,但我找不到令人满意的东西。

我的选择:

<select  ng-model= "choice.selected" ng-init = "choice.selected = historicOptions[0].id" ng-options = "historicOption.id as historicOption.value for historicOption in historicOptions">            
</select>
<br> choice : {{choice.selected}}

用于获取所选值的选项和变量(启动为默认值):

$scope.historicOptions = [
    {id: 0, value: "month"},
    {id: 1, value: "week"},
    {id: 2, value: "day"}
  ];
$scope.choice ={selected: 0};

编辑

这是我的角度应用程序(我在哪里做console.log())

var app =  angular.module('AppEfergy', []);

app.factory('historicFactory',[function(){
  var h = {
    historic: []
  };

  h.createHistoric = function(choix){
    console.log("choix = ", choix);
     if(choix == 0){
     return h.historic = [
    {date:"October"   ,consumption:230},
    {date:"September" ,consumption:235},
    {date:"August"    ,consumption:235},
    {date:"July"      ,consumption:240}
    ];
  }
   else if(choix == 1){
     return h.historic = [
    {date:"28/09/2015 - 04/10/2015" ,consumption:52},
    {date:"05/10/2015 - 11/10/2015" ,consumption:55},
    {date:"12/10/2015 - 18/10/2015" ,consumption:48},
    {date:"19/10/2015 - 25/10/2015" ,consumption:50},
    {date:"26/10/2015 - 01/11/2015" ,consumption:49}
    ];
  }
   else if(choix == 2){
     return h.historic = [
    {date:"01/11/2015" ,consumption:10},
    {date:"31/10/2015" ,consumption:11},
    {date:"30/10/2015" ,consumption:9 },
    {date:"29/10/2015" ,consumption:8 },
    {date:"28/10/2015" ,consumption:8 },
    {date:"27/10/2015" ,consumption:10},
    {date:"26/10/2015" ,consumption:9 }

    ];
  }

  };
  return h;
}]);


app.controller('MainCtrl', ['$scope','historicFactory', function($scope, historicFactory){
  $scope.choice ={selected: 0};
  $scope.choiceBis ={selected: 0};

  $scope.historicOptions = [
    {id: 0, value: "month"},
    {id: 1, value: "week"},
    {id: 2, value: "day"}
  ];

  $scope.saveOptions = [
    {id: 0, value: -10},
    {id: 1, value: -5 },
    {id: 2, value: 5  },
    {id: 3, value: 10 } 
  ];

  $scope.currentValue = 237;
  $scope.cost = 21;
  $scope.saving = 3;

     $scope.historic = historicFactory.createHistoric($scope.choice.selected); 
  console.log("choice : ", $scope.choice.selected);


}]);

和我的html页面

<!DOCTYPE html>
<html>
  <head>
    <title>Efergy App</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href ="EfergyStyle.css">

    <!-- include Angular library-->
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>

        <!-- include the AngularApp-->
    <script src="AppEfergy.js"></script>
  </head>

  <body ng-app = "AppEfergy", ng-controller = "MainCtrl">
    <header>
      Power Consumption
    </header> 
    <div class = "currentConsumption">
      <br><h2>Current Consumption</h2>
      <span class = "Value" ng-bind = "currentValue"></span>
      <span class="unit">kW</span>
    </div>

    <br>

    <div class = "historic">

      <h3>Historic</h3>
      Display an historic by 
      <select  ng-model= "choice.selected" ng-options = "historicOption.id as historicOption.value for historicOption in historicOptions">

      </select>
      <br> choice : {{choice.selected}}
     <br> 

      <table class = "historic">
        <tr>
          <th>Date</th>
          <th>Average consumption (kW)</th>
        </tr>
        <tr ng-repeat = "historics in historic">
          <td>
            {{historics.date}}
          </td>
          <td>
            {{historics.consumption}}
          </td>
        </tr>
      </table>

    </div>
  </body>
</html>

4 个答案:

答案 0 :(得分:0)

在控制器上添加以下代码

$scope.getSelectedValue = function() {
  console.log("choice : ", $scope.choice.selected);
  $scope.historic = historicFactory.createHistoric($scope.choice.selected);
};

将此事件添加到您的选择中,如下所示

ng-change="getSelectedValue()"

在您的代码中,您没有在更改选择时调用方法。这就是为什么在第一次控制器初始化时得到0作为控制台品脱的原因。

检查plunker http://plnkr.co/edit/jPBnvn6FJVHXhdEQT3QO

答案 1 :(得分:0)

您正在使用ng-options,当您想要检索所选模型但不是字符串值时,这是首选。您的示例显示您只是期望所选项目的索引。

以下代码应该可以正常工作:

<select  ng-model= "selected" 
 ng-options = "historicOption as historicOption.value for historicOption in    historicOptions"></select>
     <br> choice : {{selected.value}}

这是控制器:

 $scope.historicOptions = [
    {id: 0, value: "month"},
    {id: 1, value: "week"},
    {id: 2, value: "day"}
 ];
 $scope.selected =$scope.historicOptions[0];

以下是plunker

<强>更新 现在,如果您只想将ID用作选项的值并将值用作标签,则只需将selectng-repeat一起使用。

<select ng-model="selected">
    <option ng-repeat="option in historicOptions" 
   value="{{option.id}}">{{option.value}}</option>
</select>
<br> choice : {{selected}}

$scope.historicOptions = [
    {id: 0, value: "month"},
    {id: 1, value: "week"},
    {id: 2, value: "day"}
  ];
$scope.selected =0;

答案 2 :(得分:0)

您不应该使用ng-init = "choice.selected = historicOptions[0].id",因为这将始终显示零索引值。所以删除它并尝试使用下面的代码,如果你想下拉选定的值,那么你必须添加ng-change指令。

您的代码看起来像这样

&#13;
&#13;
var app = angular.module('AppEfergy', []);

app.factory('historicFactory', [
  function() {
    var h = {
      historic: []
    };
    h.createHistoric = function(choix) {
      console.log("choix = ", choix);
      if (choix == 0) {
        return h.historic = [{
          date: "October",
          consumption: 230
        }, {
          date: "September",
          consumption: 235
        }, {
          date: "August",
          consumption: 235
        }, {
          date: "July",
          consumption: 240
        }];
      } else if (choix == 1) {
        return h.historic = [{
          date: "28/09/2015 - 04/10/2015",
          consumption: 52
        }, {
          date: "05/10/2015 - 11/10/2015",
          consumption: 55
        }, {
          date: "12/10/2015 - 18/10/2015",
          consumption: 48
        }, {
          date: "19/10/2015 - 25/10/2015",
          consumption: 50
        }, {
          date: "26/10/2015 - 01/11/2015",
          consumption: 49
        }];
      } else if (choix == 2) {
        return h.historic = [{
          date: "01/11/2015",
          consumption: 10
        }, {
          date: "31/10/2015",
          consumption: 11
        }, {
          date: "30/10/2015",
          consumption: 9
        }, {
          date: "29/10/2015",
          consumption: 8
        }, {
          date: "28/10/2015",
          consumption: 8
        }, {
          date: "27/10/2015",
          consumption: 10
        }, {
          date: "26/10/2015",
          consumption: 9
        }];
      }
    };
    return h;
  }
]);


app.controller('MainCtrl', ['$scope', 'historicFactory',
  function($scope, historicFactory) {

    $scope.choice = {
      selected: 0
    };
    $scope.choiceBis = {
      selected: 0
    };

    $scope.historicOptions = [{
      id: 0,
      value: "month"
    }, {
      id: 1,
      value: "week"
    }, {
      id: 2,
      value: "day"
    }];

    $scope.saveOptions = [{
      id: 0,
      value: -10
    }, {
      id: 1,
      value: -5
    }, {
      id: 2,
      value: 5
    }, {
      id: 3,
      value: 10
    }];

    $scope.getSelectedValue = function() {
      console.log("choice : ", $scope.choice.selected);
      $scope.historic = historicFactory.createHistoric($scope.choice.selected);
    };

    $scope.currentValue = 237;
    $scope.cost = 21;
    $scope.saving = 3;

    $scope.historic = historicFactory.createHistoric($scope.choice.selected);
    console.log("choice : ", $scope.choice.selected);
  }
]);
&#13;
<!DOCTYPE html>
<html>

<head>
  <title>Efergy App</title>
  <meta charset="utf-8" />
  <link rel="stylesheet" href="EfergyStyle.css">

  <!-- include Angular library-->
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>

  <!-- include the AngularApp-->
  <script src="AppEfergy.js"></script>
</head>

<body ng-app="AppEfergy" ng-controller="MainCtrl">
  <header>
    Power Consumption
  </header>
  <div class="currentConsumption">
    <br>
    <h2>Current Consumption</h2>
    <span class="Value" ng-bind="currentValue"></span>
    <span class="unit">kW</span>
  </div>
  <br>

  <div class="historic">

    <h3>Historic</h3>
    Display an historic by
    <select data-ng-model="choice.selected" data-ng-change="getSelectedValue()" data-ng-options="historicOption.id as historicOption.value for historicOption in historicOptions">
    </select>
    <br>choice : {{choice.selected}}
    <br>
    <table class="historic">
      <tr>
        <th>Date</th>
        <th>Average consumption (kW)</th>
      </tr>
      <tr ng-repeat="historics in historic">
        <td>{{historics.date}}
        </td>
        <td>{{historics.consumption}}
        </td>
      </tr>
    </table>

  </div>
</body>

</html>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

我认为这是更大解决方案的一部分(即它不仅仅是一个选择框和值)。您的模板可能是结构化的,以便它启动一个新的子范围。

这意味着您的初始$scope.choice = { selected: 0 };没有做任何事情来实际设置下拉列表的选定值(要确认这一点,请尝试将所选值更改为1)。而是通过0作为第一个条目简单地设置下拉值。

更改下拉值时,只需在(原型继承的)子作用域中创建属性(而不对父作用域中现在屏蔽的选项属性执行任何操作)。

解决这个问题的最简单方法是引用父作用域中的choice属性(使用$ parent.choice) - 这是否合适取决于代码的其余部分。

这是一个说明问题的模板

小提琴 - https://jsfiddle.net/0un8p2dh/