2015-04-26 6 views
5

Есть ли трюк, чтобы получить элемент, связанный с областью действия вне директивы, которая ей владеет?Получить элемент области вне директивы

Я действую исходя из предпосылки, что это должно быть сделано в наименее благоприятных условиях (из консоли или сценария Greasemonkey). Например. для получения элемента, который имеет область применения

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

без DOM, пересекающих.

Я думаю, что можно пройти все элементы ng-scope и ng-isolate-scope DOM и отобразить их области, но я ищу более элегантное решение (карта также должна быть обновлена, и я стараюсь оставаться от DOMSubtreeModified, также это не сработает с debugInfoEnabled отключено).

+1

Вам вообще не нужна область, если вы знаете идентификатор элемента –

+0

Но как оно получается? – estus

+0

позвольте мне перефразировать вопрос, вы используете Batarang? –

ответ

7

Области (src) не содержат ссылки на элемент, с которым они связаны. В конце концов, области могут существовать без привязки к определенному элементу.

$ compile (src) является ответственным за объединение элементов с областями.

Часть процесса компиляции дополняет элемент, позволяя вам перейти от элемента >> scope (например, angular.element("#something").scope()). То же самое не происходит с областями.

Так что, чтобы перейти в другую сторону, область >> элемент, вам необходимо отобразить область видимости: Get DOM element by scope $id. Эта функция в Angular JS Batarang позволяет вам выбрать элемент со страницы и проверить связанные с ним области? Вот как это делается. Батаранг использует угловую подсказку. angular-hint выполняет итерацию по всем элементам на странице с классом ng-scope и возвращает ту, которая соответствует области ID (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; 
    } 
    } 
} 
+0

У меня ранее были проблемы с производительностью с DOMSubtreeModified с аналогичным подходом, надеюсь, что мутации наблюдатели, кэширование и дросселирование могут помочь. Спасибо за то, что вы улучшили ответ с помощью угловой подсказки, я не обратил на это внимания. – estus

0

Есть несколько вещей, которые вы можете сделать, чтобы получить элемент директивы.

Элемент по событию

Если вам нужно передать элемент по событию, вы можете создать функцию обратного вызова, который может передать элемент обратно. Если вам не нужна ссылка на него все время, это предпочтительный метод.

В возврате объекта в директиве, добавить что-то вроде

scope:{ 
     elementclicked: "&" 
    } 

В шаблоне вашей директивы, вы можете добавить

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

в контроллере директивы, теперь вы можете обработать щелчок и сдать результаты

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

Теперь вы передаете свой обратный вызов, как и любой другой, в d директива.

<yourDirective elementclicked="MyFunction(event)" ....> 

элемент при связывании

Если нужна ссылка на момент создания, вы можете сделать это, как хорошо. Если вы перейдете в структуру данных, такую ​​как настройки, вы можете установить ее в событии связывания.Когда вы свяжетесь с директивой, просто установите элемент.

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

Это будет следить за тем, когда настройки связаны и установить свойство элемента. Большой недостаток заключается в том, что вы добавляете свойство к переданному объекту, но если оно предназначено для директивы внутри директивы или это просто ваш проект, все должно быть хорошо.

Другой способ сделать это должен был бы использовать первый метод и создать обратный вызов elementlinked (element) и запустить его после связывания области.

+0

Ответ довольно описательный, но он отвечает на вопрос вопроса, а не на сам вопрос. – estus

0

Что я понял, вы хотите получить доступ к значению области вне директивы. Я сделал небольшой smaple, проверить это:

HTML Часть:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
<script data-require="[email protected]" 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 часть:

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); 
      } 
     }; 
    }); 

// Пользовательские ява скрипт

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

Для приведенного выше кода рабочего Plunker Link находится здесь: Plunker