根据我的指令,如何在父作用域上手动触发摘要循环?

时间:2015-08-04 15:26:15

标签: javascript html angularjs angularjs-directive angularjs-scope

我有一个指令,当我以编程方式对底层模型进行更改时,我想强制渲染。 $scope.$apply是惯用的。但我无法在没有重复点击UI的情况下获取指令(可能会手动强制摘要)。

有人可以帮我确定如何手动触发摘要吗?

即使this.scope.$root.$apply()也无效。

抓住父DOM节点并获取关联的范围,然后从控制台调用$apply,确实可以正常工作。

在代码中使用此DOM节点方法时,它不起作用。为什么会这样?

2 个答案:

答案 0 :(得分:4)

有两点需要注意:

  1. 范围从原型上相互继承并形成一棵树。范围引用了$parent,可以用来遍历。
  2. 摘要周期是在范围对象上发生的事情。 IE浏览器。 $scope.$digest()。这将在范围上运行摘要,然后以递归方式对所有子范围执行相同操作。 $scope.$apply()就像在做$rootScope.$digest()一样。由于它从根开始,因此它会在每个其他范围上调用摘要。因此$apply可能过多。
  3. 要回答您的问题,scope.$parent.$digest()会触发scope父母的摘要。

    但似乎触发摘要实际上并不是你的问题。 $apply将触发所有范围的摘要,因此,如果这对您不起作用,我认为您的问题不仅仅是您需要触发摘要。

    也许您不需要整个指令来重新渲染,但只需要更新它的一部分?如果是这样,请考虑绑定到某些共享服务的数据,如this

    HTML

    <div ng-app='app'>
      <one></one>
      <two></two>
    </div>
    

    JS

    angular
      .module('app', [])
      .directive('one', function() {
        return {
          restrict: 'E',
          scope: {},
          template: "<input ng-model='shared.val'> {{ shared.val }}",
          controller: function($scope, Shared) {
            $scope.shared = Shared;
          }
        };
      })
      .directive('two', function() {
        return {
          restrict: 'E',
          scope: {},
          template: '<p> {{ shared.val }}</p>',
          controller: function($scope, Shared) {
            $scope.shared = Shared;
          }
        };
      })
      .factory('Shared', function() {
        return {
          val: ''
        };
      });
    

答案 1 :(得分:1)

这在某种程度上取决于。听起来$parent就是你想要的。 scope.$root只是对$rootScope(不是您的父元素范围)的引用。简短的回答 - 试试以下......

scope.$parent.$apply()

更长的答案 - 以上假设您的孩子指令范围通过scope: true从您的父母继承。有关主题和访问父作用域的其他可能方法的更多详细信息,请参阅SO回答How to access parent scope from within a custom directive with own scope in AngularJS?在您的父作用域上获得句柄后,只需在其上调用$apply()即可。

我做了一个示例,它修改了jQuery .click()事件的父作用域。请考虑以下内容并观察父行为......

app.directive('parent', function() {
    return {
        link: function(scope, elem, attrs) {
             scope.value = 'parent'            
        }
    }
});

app.directive('child', function() {
    return {
        scope: true,
        link: function(scope, elem, attrs) {

            scope.value = 'child'

            elem.click(function() {
                scope.$parent.value = 'modded!!' // -- previously 'parent' 
                scope.$parent.$apply();
            })
        }
    }
});

JSFiddle Link - 工作示例