获取指令范围之外的范围元素

时间:2015-04-26 14:13:05

标签: javascript angularjs angularjs-scope

是否有一个技巧可以将与范围相关联的元素与拥有它的指令相关联?

我的前提是它必须在最不利条件下完成(来自控制台或Greasemonkey脚本)。例如。获取具有范围的元素

angular.element(document.querySelector('.ng-scope')).scope().$$childTail

没有DOM遍历。

我想可以遍历所有ng-scopeng-isolate-scope DOM元素并映射其范围,但我正在寻找更优雅的解决方案(地图也需要保持到约会,我试图远离DOMSubtreeModified,这也不会导致debugInfoEnabled被禁用。

3 个答案:

答案 0 :(得分:7)

范围(src)不会保留对与其关联的元素的引用。毕竟,范围可以存在而不与特定元素相关联。

$ compile (src)是负责将元素与范围相关联的人。

编译过程的一部分增加了元素,让你从元素> gt;>范围(例如angular.element("#something").scope())。范围似乎没有发生同样的情况。

所以走另一条路,范围>>元素,您必须映射范围ID:Get DOM element by scope $id。 Angular JS Batarang中的这个功能允许您从页面中选择一个元素并检查与之相关的范围?这就是它的完成方式。 Batarang使用角度暗示。 angular-hint使用ng-scope类遍历页面上的所有元素,并返回匹配作用域标识为(src: function findElt)的那个元素。

function findElt (scopeId) {
  var elts = document.querySelectorAll('.ng-scope');
  var elt, scope;

  for (var i = 0; i < elts.length; i++) {
    elt = angular.element(elts[i]);
    scope = elt.scope();
    if (scope.$id === scopeId) {
      return elt;
    }
  }
}

答案 1 :(得分:1)

您可以采取一些措施来获取指令的元素。

活动元素

如果需要在事件上传递元素,可以创建一个可以将元素传回的回调。如果您不需要一直引用它,这是首选方法。

在指令中返回对象时,添加类似

的内容
    scope:{
      elementclicked: "&"
    }

在指令的模板中,您可以添加

    <....... ng-click="ElementClicked(event)"........>

在指令控制器中,您现在可以处理点击并传递结果

$scope.ElementClicked = function ($event) {
    if ($scope.elementclicked != undefined) {
        elementclicked({ event: $event });
    }
}

现在,您可以将回调传递给指令。

    <yourDirective   elementclicked="MyFunction(event)" ....>
链接时

元素

如果您在创建时需要参考,也可以这样做。如果您传入数据结构(如设置),则可以在链接事件中进行设置。在指令中进行链接时,只需设置元素。

scope:{
        settings:"="
},
link:function(scope,element){
    scope.$watch('settings',function(){
        if(scope.settings!=undefined){
            scope.settings.element=element;
        }
}
}

这将监视绑定设置的时间并设置element属性。这里的一大缺点是你要将一个属性附加到一个传递的对象,但是如果它是一个指令内的指令,或者它只是你的项目,它应该没问题。

另一种方法是使用第一种方法并创建一个elementlinked(元素)回调并在链接范围后触发它。

答案 2 :(得分:0)

我理解的是,您希望在指令之外访问范围的值。我做了一个小小的,检查一下:

HTML部分:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>

  <div id="outer" ng-app="plunker" ng-controller="MainCtrl">
    You are {{msg}}
</div>
<div onclick="change()">click me</div> 

Scipt part:

var app = angular.module('plunker', []);

    app.controller('MainCtrl', function($scope, $rootScope) {
     $scope.msg = "great";
        $rootScope.safeApply = function( fn ) {
            var phase = this.$root.$$phase;
            if(phase == '$apply' || phase == '$digest') {
                if(fn) {
                    fn();
                }
            } else {
                this.$apply(fn);
            }
        };
    });

//自定义java脚本

function change() {
    var scope = angular.element($("#outer")).scope();
    scope.safeApply(function(){
        scope.msg = 'Superhero';
    })
}

对于上面的代码,Plunker Link就在这里:Plunker