AngularJs斗争经验总结(一)

AngularJs 非常强大,它彻底摆脱了传统的前端开发方式,无缝的进行数据绑定,使用它做前端开发着实方便快速。最近开始使用它做项目开发,过程中吃了不少瘪,特此记录一下。

使用自身特性

开始使用AngularJs开发时,还是难免摆脱传统的思维方式,有些地方仍然使用Jquery动态修改数据和绑定事件(会被耻笑啊),其实AngularJs提供的特性已经能够满足我们大部分的需求。拿 inputselect 标签举例说明:

  1. input 不要使用 value 属性,尽可能使用 ng-model 指令。数据变化时,不会存在 value 和 defaultValue 不一致的问题。
  2. 尽可能使用 ng-keyupng-blurng-click 等指令进行事件处理。避免使用Jquery进行DOM绑定。
  3. select 要使用 ng-modelng-options 指令,这将大大减少模板的复杂度。

事件并发问题

有这样一个场景,ng-blur 会触发指定的操作同时 ng-change  在一定条件下会触发 ng-blur 事件,示例代码如下:

HTML

<input type="number" min="0" class="mi-input mi-input-transparent"
       value="{{emission.a}}"
       ng-model="emission.a"
       ng-model-options="{ updateOn: '' }"
       ng-keyup="onInputKeyUp($event)"
       readonly required
       ng-dblclick="onInputDblClick($event)"
       ng-blur="onInputBlur($event)"/>

Javascript

$scope.onInputKeyUp = function (event) {
  if (event.keyCode == 13) {
    event.target.blur();
  }
};
$scope.onInputBlur = function (event) {
  //TODO
};

以上代码运行后会出现报错“$rootScope:inprog: $apply already in progress error.

为何会出现这样的错误,我们先了解下这段代码运行过程:

  • 输入回车
  • ng-keyup 触发,开始解释执行
  • 调用 target.blur() 事件
  • ng-blur 触发并且尝试一个新的执行周期
  • 然后AngularJs就不干活了

事实上,在 keyup 的处理还没有完成时,blur 同步执行并且迅速触发了处理程序,这可能是 AngularJs 的一个 bug,可以使用 $timeout 解决这个问题。

$scope.onInputKeyUp = function (event) {
  if (event.keyCode == 13) {
    $timeout(function () {
      event.target.blur()
    }, 0, false);
  }
};

先写到这儿吧,有时间继续补充。

发表评论