2015-04-03 2 views
0

Например, у меня есть следующий HTML:делает угловое создание нового дерева DOM после этапа компиляции или продолжения работы с оригинальным измененным DOM?

<div dir-parent> 
    <div dir-child1></div> 
</div> 

Во время фазы компиляции директивы dirParent получит шаблон DOM элемент, который имеет внутри него в div с dirChild1 директивы. Если я не изменю этот html внутри функции компиляции dirParent, тогда функция компиляции вызывается для директивы dirChild1. Однако, если я удалю <div dir-child1="" some-child1-attr></div> внутри функции компиляции dirParent, то угловая продолжает обрабатывать этот измененный DOM, который больше не имеет div с директивой dir-child1, и поэтому функция компиляции для директивы dir-child1 никогда не выполняется.

Я предположил, что после выполнения углового выполнения функции компиляции он строит новый DOM от htmlизменен во время компиляции. Правильно ли это предположение? Этот изменен DOM представляется экземпляром Элементы DOM и доступны во время фазы pre-link, поэтому я предполагаю, что это фаза, когда угловые элементы экземпляров создают дерево DOM.

+0

Что вы подразумеваете под _ready_? Вы уже знаете, что элемент создан на шаге 1. Его можно изменить на любом из следующих шагов. – zeroflagL

+0

Я полностью переписал свой вопрос, чтобы уточнить, что я прошу –

+0

@zeroflagL, исследовал вопрос, пожалуйста, посмотрите мой ответ, если он будет заинтересован. –

ответ

1

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

var element = $("body"); 
compile(element)($rootScope); 

function compile(DOMElementsTree) { 
    var compositeLinkFn = compileNodes(DOMElementsTree); 
    return function publicLinkFn(scope) { 
     var $linkNode = DOMElementsTree; 
     compositeLinkFn(scope, $linkNode); 
     return $linkNode; 
    } 
} 

function compileNodes(nodesList) { 
    var linkFns = []; 

    nodesList.forEach(function (node) { 
     var nodeLinkFn = applyDirectivesToNode(node); 
     var childNodes = nodesList.childNodes; 
     var childLinkFn = !!childNodes.length ? compileNodes(childNodes) : null; 
     if (nodeLinkFn || childLinkFn) { 
      linkFns.push(i, nodeLinkFn, childLinkFn); 
     } 
    }); 

    return function compositeLinkFn(scope, nodeList) { 
     linkFns.forEach(function (linkFn) { 
      var nodeLinkFn = linkFn[1]; 
      var childNodeLinkFn = linkFn[2]; 

      if (nodeLinkFn) { 
       nodeLinkFn(childLinkFn, scope, nodeList); 
      } else if (childNodeLinkFn) { 
       childLinkFn(scope, nodeList) 
      } 
     }); 
    } 
} 

function applyDirectivesToNode() { 
    // this is where compile functions of all directives on a node are executed 
} 

function nodeLinkFn() { 
    // here pre link and post link functions are executed 
} 

function childLinkFn() { 
    // here pre link and post link functions are executed 
} 

Вы можете видеть, что applyDirectivesToNode, который выполняет функцию compile директивы не возвращает новый узел DOM, вместо этого он изменяет DOMElementsTree, что он получает с помощью ссылок и compositeLinkFn продолжает работать с этим экземпляром DOM.

Изначально у меня был этот кусок образец кода в мой вопрос с from here:

var $compile = ...; // injected into your code 
var scope = ...; 
var parent = ...; // DOM element where the compiled template can be appended 

var html = '<div ng-bind="exp"></div>'; 

// Step 1: parse HTML into DOM element 
var template = angular.element(html); 

// Step 2: compile the template 
var linkFn = $compile(template); 

// Step 3: link the compiled template with the scope. 
var element = linkFn(scope); 

// Step 4: Append to DOM (optional) 
parent.appendChild(element); 

Таким образом, в этом экстракте последний шаг имеет дело с результатом функции publicLinkFn, а именно $linkNode в моем коде выше.

0

Элемент DOM действительно создан во время шага 1, однако он доступен только в памяти браузера, но не отражается в фактической странице DOM.

Поскольку элемент был создан из Javascript (var html = ...) после его компиляции и привязки, вам нужно вернуть его на страницу с помощью append, чтобы пользователь мог видеть и взаимодействовать с ним.

Обновление Я не понимаю, что вы спрашиваете точно, но я не думаю, что вы найдете ответ на StackOverflow. Вам нужен форум или дополнительная лекция о внутренней функции AngularJS. Я настоятельно рекомендую вам прочитать эту статью: http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives/

Update2 Из моего понимания (и Accoding к цитированной выше статье), Угловая сначала компилировать шаблон из dir-parent, а затем компилировать его дети используя тот же шаблон. Если вы изменили этот шаблон во время верхней фазы компиляции, например, удалив dir-child1, тогда больше нечего компилировать, а затем «Угловая» будет начинаться с pre-link и, наконец, post-link.

+0

Спасибо, см. Мое обновление. –

+0

Я обновил свой ответ, извините, что больше не могу помочь – floribon

+0

Да, вижу, спасибо. Связанная с вами статья - это описание верхнего уровня, в то время как я заинтересован в более глубоком понимании. Иногда я читаю исходный код angular.js, чтобы получить желаемое знание, но это немного сложно понять. Спасибо, в любом случае, лучше всего! –