数据双向绑定页面无反应(angularjs)

问题引入

使用 angularjs进行过一段时间的开发后,基本上都会遇到一个这样的坑:页面进行了双向数据绑定,控制层的数据也已经改变了,但是视图层的数据却没有改变。

其实造成这个问题的原因大致分为以下几个

  1. scope作用域发生的继承
  2. 操作了dom层,数据更改,却没有触发angularjs的服务。没有更新视图层。

scope作用域的继承

先看个实例。

<div ng-controller="TestCtrl">
  <p>{{name}}</p>
  <div ng-if="show">
    <input type="text" ng-model="name">
  </div>
</div>
<script>
function TestCtrl($scope){
    $scope.show = true;
    $scope.name = 'htf';
}
</script>

上面的code,按道理说,我们在改变input的值时,变量name的值应该会因为数据的双向绑定而进行改变,与input的value保持一致。

但是,实际上却没有发生视图上的变化。原因就是因为ng-if会隔离作用域,创建新的作用域。使得scope.name压根与input里的name不是一个作用域上的值,自然无法做出更改。

作用域

每个 Angular 应用默认有一个根作用域 $rootScope, 根作用域位于最顶层,从它往下挂着各级作用域。

通常情况下,页面中 ng-model 绑定的变量都是在对应的 Controller 中定义的。如果一个变量未在当前作用域中定义,JavaScript 会通过当前 Controller 的 prototype 向上查找,也就是作用域的继承。

这种情况也可以通过scope.$parent进行访问。

上下级作用域共用变量

可使用引用类型变量。

<div ng-controller="OuterCtrl">
  <p>{{x}}</p>
  <div ng-controller="InnerCtrl">
    <input type="text" ng-model="x">
  </div>
</div>
<script>
function OuterCtrl($scope){
    $scope.data = {};
    $scope.data.x = 'hello';
}
function InnerCtrl($scope){
}
</script>

 如上,便可实现理想中的数据双向绑定。

ng-if的作用域

在这种情况下,两者的 data 是同一个引用,对这个对象上面的属性修改,是可以反映到两级对象上的。

前面讲的是两级控制器之间的作用域,那跟前面提到的问题有什么关系呢?那个看着不是只有一个 Controller 吗?

其实,并不是只有 Controller 可以创建作用域,ng-if 等指令也会(隐式地)产生新作用域。

总结下来就是,ng-if、 ng-switch 、 ng-include 等会动态创建一块界面的东西,都是自带一级作用域。

因此,在开发过程中,为了避免模板中的变量歧义,应当尽可能使用命名限定,比如 data.x,出现歧义的可能性就比单独的 x要少得多。

总结

始终将页面中的元素绑定到对象的属性(data.x)而不是 直接绑定到基本变量(x)上。

posted @ 2018-12-12 14:34  我叫悠哉  阅读(2821)  评论(0编辑  收藏  举报