一尘不染

ng-model未在范围外更新

angularjs

ng-model将an 绑定到输入,但是绑定到该变量的值未div在该指令声明的位置之外进行更新:

<div input-field
     ng-if="startTypes.selected.value == 'LocalDate' || startTypes.selected.value == 'LocalDateTime'">
  <input id="date" type="text" ng-model="date" input-date>
  <label for="date">Date</label>
  Date inner scope: {{date}}
</div>
Date outer scope: {{date}}

选择新日期时,仅内部date会更新。外部的那个仍然是旧值(可能undefined取决于我是否在控制器中声明了它,这无关紧要)。

我正在使用angular-materialize,我不确定这是否是问题的根源,但是没有意义,因为这是与CSS框架materializecss一起使用的特定的angular框架。

是我正在使用的组件。

编辑:

我试过date在控制器中声明为,$scope.date = new Date()并且确实将当前日期加载到日期选择器中。但是,当选择日期并更改模型时,只会在本地(内部范围)进行更新,而在外部范围中则保留旧值。


阅读 213

收藏
2020-07-04

共1个答案

一尘不染

As ng-if创建一个子作用域,该子作用域在将内部模板插入DOM时从其当前作用域原型继承而来,因此在这种情况下ng-model将在其ng- if子作用域内创建。因此,发生的事情是在创建一个child scopeprimitive数据类型值和reference(对象)数据类型值携带到子作用域时,这就是为什么您可以看到外部作用域dateng- if日期字段(仅第一次)中获取值的原因。但是,当您更新值时,date您将看不到该值被更新到外部范围。因为该方式child scope具有创造primitive type价值,所以不携带其引用,而对象随其引用一起携带。所以你可以创建一个像$scope.model = {}&然后在其中定义一个属性,它将起作用。因为对象带有它们对子作用域的引用,所以更新内部对象也将同步外部对象(它们都是相同的)。可以使用此规则Dot Rule来解决问题。

$scope.model = {};
$scope.model.date = new Date();

避免这种范围层次结构的更方便的方法是controllerAs在HTML上使用控制器时使用模式。在这种情况下,您不应该使用$scope所有属性,而是将所有属性绑定到控制器功能上下文(this)。此后,在使用controller时,您可以使用aliascontroller来获取controller的值,例如ng- controller="myCtrl as vm"(这vm是controller的别名,其中所有信息都绑定到this

的HTML

<div input-field
     ng-if="vm.startTypes.selected.value == 'LocalDate' || vm.startTypes.selected.value == 'LocalDateTime'">
  <input id="date" type="text" ng-model="vm.date" input-date>
  <label for="date">Date</label>
  Date inner scope: {{vm.date}}
</div>
Date outer scope: {{vm.date}}
2020-07-04