模态中的angularstrap typeahead会多次触发每次更改

时间:2014-09-03 12:52:52

标签: angularjs typeahead angular-strap

我在angularStrap模式中有一个angularStrap typeahead,typeahead控件正常工作,除了更改事件重复的时间与模式自创建以来打开/关闭的时间一样多。

似乎每次显示模态时都会将侦听器添加到typeahead,但我找不到解决此问题的方法。也许不是一个错误,而是我身边的误用。

例如,如果模态已打开然后关闭3次,则第4个打开并输入打印头将触发对每个键入字符的 getParentItem 处理程序(见下文)的4个调用。 ..

我无法发布图片,因为这是我的第一个问题,但Chrome控制台提供了类似这样的内容(其中数字是一行中以蓝色圆圈直观显示的相同日志的数量):

  • getParentItem =>未定义
  • getParentItem =>我
  • getParentItem =>它
  • getParentItem => ITE
  • 2 getParentItem =>未定义
  • 2 getParentItem =>我
  • 2 getParentItem =>它
  • 2 getParentItem => ITE
  • 3 getParentItem =>未定义
  • 3 getParentItem =>我
  • 3 getParentItem =>它
  • 3 getParentItem => ITE
  • 4 getParentItem =>未定义
  • 4 getParentItem =>我
  • 4 getParentItem =>它
  • 4 getParentItem => ITE

环境:

  • AngularJS v1.3.0-build.3029 + sha.7df7d1a
  • AngularStrap @version v2.0.5 - 2014-08-07

代码如下: module.js 中 我已经改变了模式处理方式,以确保每次都不重新创建模态并拥有多个实例。问题无论哪种方式都是一样的。

...
/**
 * Edit item creating modal if required
 */
$scope.editItem = function(event) {
  if ('undefined' === typeof this.modalEdit) {
    this.modalEdit = $modal({
      scope: this,
      animation: 'am-fade-and-scale',
      title: 'Insert/Edit Item',
      template: 'partials/item.html',
      show: false
    });
  }
  this.showModalEdit();
};
/*
 * Show edition modal
 */
$scope.showModalEdit = function() {
  this.modalEdit.$promise.then(this.modalEdit.show);
};
/*
 * Hide edition modal
 */
$scope.hideModalEdit = function() {
  if ('undefined' !== typeof $scope.modalEdit) {
    $scope.modalEdit.hide();
  }
};
 /*
 * Propose parent items according val
 */
$scope.getParentItem = function(val) {
  console.info('getParentItem => ' + val);
  if ('undefined' !== typeof val && 2 < val.length) {
    $http.get('/api/items/' + val, {})
      .success(function(data, status, headers, config) {
        console.log('success');
      })
      .error(function(data, status, headers, config) {
        console.log('error');
      });
  }
};
...

在模态模板 item.html

<div class="modal" tabindex="-1" role="dialog">
  <div class="modal-dialog">
    <form method="post" ng-submit="upsert()" ng-controller="ItemCtrl">
      <div class="modal-content">
        <div class="modal-header">
          <h3 class="modal-title" ng-bind="title"></h3>
        </div>
        <div class="modal-body">
          ...
          <div class="form-group">
            <h5>Parent Item</h5>
            <input class="form-control input-sm" type="text" ng-model="item.parent" name="parent" data-animation="am-flip-x" data-limit="25" ng-options="item.uid as item.label for parent in getParentItem($viewValue)" placeholder="Select a parent item" bs-typeahead required autofocus>
          </div>
          ...
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-sm" ng-click="$hide()">Cancel</button>
          <button type="submit" class="btn btn-primary btn-sm">Validate</button>
        </div>
      </div>
    </form>
  </div>
</div>

任何想法都会受到欢迎,因为我已经花了很多时间在这个问题上多次重构我的代码并且在reusing modal fires multiple times之外的任何地方都没有发现任何问题,但没有跟进......

1 个答案:

答案 0 :(得分:0)

在我的控制台上经过几次测试和小时后,我发现为模态创建一个新的范围确实解决了这个问题。可能由于角度和继承行为的范围管理,我还没有完全理解。

解释(观察但未完全理解)

使用控制器范围本身作为我之前所做的模态(&#34;范围:此&#34;或&#34;范围:$ scope&#34;)导致相同的$$观察者的范围被堆叠每当我打开模态(模态属性的观察者)时,之前的模型永远不会被释放/销毁,在模态的一些打开/关闭之后结束于几十/几百个观察者工作触发相同的事件。

注意:

  • 在角度范围的这个旅程中,我发现比从模态范围调用主范围的函数(例如getParentItem),&#34; $ scope&#34;是指&#34;这个&#34;正在引用本地范围本身(即模态或控制子范围),这似乎是合乎逻辑的。我没有完全理解指令中的范围创建过程......虽然尝试阅读:https://github.com/angular/angular.js/wiki/Understanding-Scopeshttp://thenittygritty.co/angularjs-pitfalls-using-scopes,但这对我和现在都是如此。
  • 我不再需要打扰创建和使用一个模态,新的范围是通过模态方法本身提供的,虽然我不确定它在内存使用方面是否安全。< / LI>
  • modalEdit已成为var也不再是范围属性。
  • 我没有(并且仍然没有)为模态创建一个特定的控制器(例如在ng-controller中绑定),因为我在模块/控制器/服务中有其他交互,在upsert中过程主要是我无法轻易解决,可能是因为我缺乏知识,因为它是我使用角度的第一个项目。

我的工作代码是:

$scope.editItem = function(item) {
  var editionScope = $scope.$new(true);
  editionScope.getParentItem = $scope.getParentItem;
  editionScope.upsertItem = $scope.upsertItem;
  editionScope.modes = $scope.modes;
  editionScope.item = item;
  modalEdit = $modal({
    scope: editionScope,
    animation: 'am-fade-and-scale',
    title: 'Item Edition',
    template: 'partials/item.html',
    show: true
  });
};