射击破坏而不创建孤立的范围

时间:2014-03-18 21:20:44

标签: javascript angularjs

用例

我正在处理的应用程序非常动态。输入基于模板变量动态变化。我拥有的指令基于各种范围变量,将获取必要的模板并构建html输出。事件也与这些模板中的每一个相关联,因此需要销毁childScope,以便在范围更改时触发相应的销毁事件。特别是,我发现如果我不调用destroy方法,就会发生内存泄漏。

[编辑] 为了进一步扩展定义,基本上我们有一个通用小部件。对于可以看到按钮的人,可以根据单击的次数更改值。对于视障人士,此按钮将呈现为单选按钮列表。按钮基本上是"热点"渲染在图像上。这用于评估关节的疼痛评分。但是,有视力障碍的患者无法看到按钮,但屏幕阅读器可以读出无线电输入。平板电脑用于数据采集并在研究人员,患者和医生之间传递。切换按钮将在视觉模式和视觉受损模式之间切换,因为医生更快地理解图像视图。 WiFi是一个问题,因为在医院的连接是不稳定的,所以我使用角度来为此制作SPA。

它是如何工作的是有一个名为template的变量,它被传递给指令。该链接将读取此变量并加载缓存的相应模板。按下按钮时,模板可能会更改,链接将重新读取。我发现的问题是当我从滑块切换到视障人士的无线电列表输入时,jQuery滑块会导致内存泄漏。切换视图的次数越多,消耗的内存就越多。但是,如果在$ compile之前调用destroy方法,则内存泄漏问题会消失。不幸的是,调用scope。$ destroy会破坏所有内容,因此使用了childScope来阻止这种情况。

这可以使用模板变量上的ng-if或ng-switch完成,但是,我们采用了编程路由,因为基本上,即将出现的要求是这些窗口小部件应该在多个视图中动态更改。目前我们只有视力和视力障碍模式,但他们也希望它具有医生视图","研究者视图","患者视图",&#34 ;患者视力受损视图","老年人视图"等等......根据视图,小部件将改变其外观和功能。即一些观点可能有其他行为。

问题

我无法将模型绑定到生成的childScope。我认为根本问题是 $ new()创建了一个孤立的范围,所以我怀疑它无法与外界沟通。但是,我真正想做的是正确地破坏范围以避免内存泄漏。

我的问题是:

  • 有没有办法让childScope与父ng模型绑定?
  • 还有另一种方法可以消灭吗?

代码

这是我的非工作代码的简化版本。我已经删除了大部分复杂性,将其降低到基本组件。

模板

<div ng-app="app" ng-controller="ctrl">
    <div>
        <h1>Input</h1>
        <doodad ng-model="foo"></doodad>
        <nested-doodad ng-model="bar"></nested-doodad>
        <nested-doodad ng-model="qux.value"></nested-doodad>
    </div>
    <div>
        <h1>Output</h1>
        <span>{{ foo }}</span>
        <span>{{ bar }}</span>
        <span>{{ qux | json }}</span>
    </div>
</div>

应用

    function ctrl($scope) {
    $scope.foo = "foo";
    $scope.bar = "bar";
    $scope.qux = { value : "qux" };
}
angular
  .module('app', [])
  .directive('doodad', function($compile) {
      var linker = function(scope, element) {
          var childScope;

          /* Used to fire destroy on child widgets */
          var getNewScope = function(oldScope) {
            if (oldScope) {
                oldScope.$destroy();
                oldScope = null;
                element.html('');
            }
            return scope.$new();
          };

          var renderTemplate = function() {
              childScope = getNewScope(childScope);
              /* template is dynamic - hardcoded for example */
              /* events & lots of other funny stuff are bound here */
              element.html('<input type="text" ng-model="ngModel" />');
              $compile(element.contents())(childScope);
          }

          scope.$watch('template', renderTemplate);
      }
      return {
          restrict: 'E',
          replace: true,
          require: '^ngModel',
          scope: {
              ngModel : '=',
              template: '='
          },
          link: linker
      }
  })
  .directive('nestedDoodad', function() {
      return {
          restrict: 'E',
          replace: true,
          scope: {
              ngModel : "="
          },
          template: '<div><doodad ng-model="ngModel"></doodad></div>'
      }
  });

JSFiddles

1 个答案:

答案 0 :(得分:0)

  

有没有办法让childScope与父ng模型绑定?

$scope = $parent.$scope;
  

还有另一种方法可以消灭毁灭吗?

angular.element(document).injector().get('$rootElement').removeClass("ng-scope")

<强>参考