是否有一个技巧可以将与范围相关联的元素与拥有它的指令相关联?
我的前提是它必须在最不利条件下完成(来自控制台或Greasemonkey脚本)。例如。获取具有范围的元素
angular.element(document.querySelector('.ng-scope')).scope().$$childTail
没有DOM遍历。
我想可以遍历所有ng-scope
和ng-isolate-scope
DOM元素并映射其范围,但我正在寻找更优雅的解决方案(地图也需要保持到约会,我试图远离DOMSubtreeModified
,这也不会导致debugInfoEnabled
被禁用。
答案 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