【问题标题】:The ngChange expression is evaluated when array/object used in ngOptions is set to empty/undefined/null当 ngOptions 中使用的数组/对象设置为空/未定义/空时,评估 ngChange 表达式
【发布时间】:2016-07-28 18:15:01
【问题描述】:

我刚刚在 Angular.js 中发现了一个奇怪的功能/错误。

假设我们有一个选择框,其中的选项由 ngOptions 指令填充。我们使用 ngChange 指令在选择框上设置了一个更改监听器。

<select ng-model="model" ng-options="item for item in list" ng-change="foo()"></select>

我们定义范围如下:

$scope.list = [1,2,3,4,5];
$scope.model = 3;

$scope.foo = function() {
    console.log("change");
};

然后我们在代码中的某个地方像这样重置数组:

$scope.list = [];

如果我们查看控制台,我们可以看到函数 foo() 被调用并且文本 "change" 被记录。但是,用户没有触摸选择框,也没有更改所选值。根据文档

ngChange 表达式仅在输入发生更改时进行评估 value 会导致将新值提交给模型。

它将不被评估

  • 如果从 $parsers 转换管道返回的值没有改变
  • 如果输入继续无效,因为模型将保持为空
  • 如果模型以编程方式更改,而不是通过更改输入值

输入值更改。模型更改。只有用于生成选项的数组(使用对象时行为相同)以编程方式进行了更改。

通过检查 select 元素,我还发现 ng-dirty 类已设置为该元素,即使用户从未触摸过选择框(ng-untouched 类仍然设置)。

为什么会这样?这是一个我无法理解的奇怪功能还是一个错误?难道我做错了什么?你知道这个问题的解决方案吗?

【问题讨论】:

  • 输入值 is 在您修改用于生成选项的数组后立即更改。
  • 这不是真的。我可以随意修改数组(添加/删除元素,替换整个数组)并且模型不会改变,不会评估 ngChange 表达式。这是预期的行为。只有空/未定义/空数组/对象会导致意外行为。
  • 你有$scope.model = 3;。在您看来,输入{{model}} 并在您调用任何代码集$scope.list = [] 时观察变化。
  • 与此同时,我还发现model 设置为null,而list 不再包含所选值。但你的评论说有些不同。 如何修改数组很重要。但这仍然是一种奇怪且出乎意料的行为。当您为模型分配一个不在列表中的值时,没有问题。你可以这样做,一个带有新值的空选项将被添加到选择框中。那么为什么当你以相反的顺序执行时,模型应该设置为null
  • 最重要的是:在这种情况下,模型是由角度(由程序更改触发)而不是用户更改的。因此,没有逻辑理由来评估 ngChange 表达式,该表达式是为用户通过单击更改输入的情况设置的。也许我应该访问 Angular 的 github 页面来讨论这个“功能”。你怎么看?

标签: angularjs drop-down-menu ng-options angularjs-ng-change


【解决方案1】:

当你设置列表时:

$scope.list = [];

这会触发 ng-change,因为它会更改选项列表,从而更改输入值。

我看到您强调了:如果模型以编程方式更改,而不是通过更改输入值

在这种情况下,您不会以编程方式更改模型。

【讨论】:

  • 没错,在这种情况下,我不会以编程方式更改模型。 Angular 正在改变模型。什么是非常重要的。请参阅我对我的问题的评论。
猜你喜欢
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
相关资源
最近更新 更多