AngularJS 1.4:Select 使用 $compile 插入列表时,列表值未正确初始化

AngularJS 1.4: Select List Value not Initializing Correctly when List is Inserted with $compile

这里有一些快速的背景信息。我刚刚升级到 Angular 1.4。我正在使用用 C# 编写的 API 进行服务器端调用。

我页面的一部分显示了 2 个 select 列表(项目和子项目)。两者都应该默认为“(Select a ______)”,我将其列为每个 select 的第一个选项,其中 "value" 为 0。适当的 ng-model变量初始化为 0。

select 列表的实际 HTML 代码是在服务器端使用字符串连接生成的,通过 $http 传递给客户端,并使用调用 $compile (一点也不理想,但我的客户几乎把我束缚在这个API)。在 1.4 更新之前,一切都运行良好。

现在,我的项目 select 列表默认为空。当我检查元素时,这就是我所看到的...

<select ng-change="updateSubProjList()" ng-model="curProjID">
    <option value="? number:0 ?"></option>
    <option value="0">(Select a Project)</option>
    <option value="1">First Project</option>
    <option value="2">Second Project</option>
    ...
</select>

...第一个“?number:0?”条目是当前 selected 的条目。我的子项目 select 列表仍然初始化得很好,这让这更奇怪了。

我知道在 AngularJS 1.4 的更新中对 $compile 进行了一些更新,但我找不到解决我的问题的方法。如有任何帮助,我们将不胜感激。

在 1.4 中似乎有一个变化与所选选项如何与 ngModel 相匹配,通过比较 <option value="0"> 中的 value 属性 - 它现在需要明确使用要匹配的字符串,而不是整数。

事实上,documentation明确指出:

The value of a select directive used without ngOptions is always a string. When the model needs to be bound to a non-string value, you must either explicitly convert it using a directive ... or use ngOptions to specify the set of options.

要修复,请将 $scope.curProjID 的初始化值更改为字符串:


$scope.curProjID = "0"; // instead of $scope.curProjID = 0;

当没有匹配项时(也没有,除非你分配一个字符串 "0"),select 添加一个 "unknown" 选项:<option value="? number:0 ?"></option>.

我遇到了同样的问题。我没有确保我的 JavaScript 代码到处都使用字符串,而是执行了以下操作:

Removed the <option ...> items from the HTML file

Introduced a list into JavaScript, similar to:

var orderQuantities = [
        { id: 100, text: '100' },
        { id: 200, text: '200' },
        { id: 300, text: '300' },
];

Did make sure that orderQuantities is visible in the scope

Used ng-option in the select tag as follow:

<select ng-model="vm.entity.OrderQuantity" ng-options="orderQuantity.id as orderQuantity.text for orderQuantity in vm.orderQuantities"></select>

还有另一种方法:使用实现解析器和格式化程序的指令。参见 http://plnkr.co/edit/JZPay8jgm5AXKGXDCjSb

感谢 narretz!

伪代码:

<select convert-number ng-model="x">
   <option value="100">100</option>
   <option value="200">200</option>
</select>


app.directive('convertNumber', function() {
  return {
    require: 'ngModel',
    link: function(scope, el, attr, ctrl) {
      ctrl.$parsers.push(function(value) {
        return parseInt(value, 10);
      });

      ctrl.$formatters.push(function(value) {
        return value.toString();
      });      
    }
  }
});
<select ng-model="x">
   <option value="100">100</option>
   <option value="200">200</option>
</select>

scope.x = '200'

或阅读此文档。 https://docs.angularjs.org/guide/migration