2016-09-16 1 views
2

Ich entwickle eine Angular-Anwendung, die in SharePoint 2013 gehostet wird, und (glaube ich) Probleme mitund $ariaProvider."ngAria" mit angularem Material "deaktivieren"

Das Problem ist, wenn ich auf einen Link klicke, um ein <md-dialog> Element als ein modales zu öffnen, wird der UI-Thread für ~ 30-40 Sekunden gesperrt. Durch das Debugging kann ich es auf eine einzige Methode zurückführen, die im Angular Material .js mit dem Namen walkDOM(element) enthalten ist.

Die Anwendung funktioniert lokal (ohne SharePoint) aber hängt in der SharePoint-Umgebung. Ich denke, dass diese Methode problematisch ist, da der DOM-Baum, den es in SharePoint durchquert, wesentlich größer ist als der in der Entwicklung. Nachdem das Ereignis modal open ausgelöst wurde, wird die Methode walkDOM() ausgelöst und fügt den meisten DOM-Elementen einen Wert aria-hidden="true" hinzu. Aufgrund der komplexen DOM-Struktur, die SharePoint hat, glaube ich, dass dies das Aufhängen verursacht. Ich bin in der Lage zu debuggen und zu sehen, wie die Breakpoints kontinuierlich feuern. Ich kann auch sehen, dass die Attribute nach dem Auflegen hinzugefügt werden und nicht vorher vorhanden sind.

Ich möchte diese Traversal deaktivieren, aber bisher keinen akzeptablen Weg gefunden haben, dies zu tun. Ich bin diesem Thema gefolgt und bin zu der Erkenntnis gelangt, dass ich möglicherweise nicht auf die Methoden zugreifen kann, an denen ich interessiert bin: https://github.com/angular/material/issues/600. Ich verstehe, dass die Deaktivierung von Aria eine schlechte Übung ist, aber ich versuche lediglich, die Durchquerung des DOM zu verhindern, die dazu führt, dass der UI-Thread so lange gesperrt ist. Ich habe den folgenden Code versucht, die Aria Komponenten für die Winkel App zu überschreiben/konfigurieren (letztere Schnipsel in diesem Thread vorgeschlagen: How do I disable ngAria in ngMaterial?):

angular 
.module('app', ['ui.router', 'ngMaterial', 'ngAria']) 
... 
.config(function ($ariaProvider) { 
    $ariaProvider.config({ 
    ariaValue: true, 
    ariaHidden: false, 
    tabindex: false 
    }); 
}) 
.decorator('$mdAria', function mdAriaDecorator($delegate) { 
    $delegate.expect = angular.noop; 
    $delegate.expectAsync = angular.noop; 
    $delegate.expectWithText = angular.noop; 
    return $delegate; 
}); 

Gibt es eine Möglichkeit das ich tun kann, was ich tun möchte? Ich möchte vermeiden, die Anwendung neu zu schreiben, um modals wenn möglich nicht zu verwenden. Ich dachte darüber nach, eine globale walkDOM() Methode zu schreiben, hatte aber wenig Erfolg.

Jede Hilfe würde sehr geschätzt werden. Vielen Dank!

BEARBEITEN: Dies ist ein Problem mit der Art und Weise, aria Attribute der DOM-Struktur und der Art, wie die walkDOM()-Methode funktioniert. Dies hat nichts mit Routing/Modellzustandsverwaltung zu tun, wie in dieser Frage angesprochen: How to prevent view redraw when changing route in AngularJS.

+0

[walkDom] (http://www.javascriptcookbook.com/article/Traversing-DOM-subtrees-with-a-recursive-walk-the -DOM-Funktion /) ist eine DOM-Traversing-Funktion von Doug (AFAIK). Verwechsle das nicht, da es auch von anderen Orten verwendet werden kann. Haben Sie einen Verweis auf einen Code in ngMaterial, der "walkDOM" implementiert? – sabithpocker

+0

@sabithpocker die Methode, die ich sehe sieht aus wie es speziell für Dialoge ist: https://github.com/angular/material/blob/fc7e9b3fc87713c6fde3b82c0df358650ec9aafc/src/components/dialog/dialog.js – awh112

+0

Danke für den Kommentar @PaulSweatte, aber ich denke, der Link, den du gepostet hast, ist ein anderes Thema als das, auf das ich gestoßen bin. Das Problem, auf das ich oben einging, ist ein Problem mit dem Angular Material-Code und wie er große DOM-Strukturen durchläuft. – awh112

Antwort

0

Verwenden Sie einen Getter, um die parentNode Attributprüfung innerhalb von walkDOM abzufangen. Zum Beispiel:

function getter() 
 
    { 
 
    return document.documentElement; 
 
    } 
 

 
function isNodeOneOf(elem, nodeTypeArray) 
 
    { 
 
    if (nodeTypeArray.indexOf(elem.nodeName) !== -1) 
 
    { 
 
    return true; 
 
    } 
 
    } 
 

 
function walkDOM(element) 
 
    { 
 
    var isHidden; 
 
    var children = element.parentNode.children; 
 

 
    console.log(Date() + element.innerText); 
 
    
 
    while (element.parentNode) 
 
    { 
 
    if (element === document.body) 
 
     { 
 
     console.log(Date()); 
 
     return; 
 
     } 
 
    
 
    
 
    for (var i = 0; i < children.length; i++) 
 
     { 
 
     console.log(Date()); 
 
    // skip over child if it is an ascendant of the dialog 
 
    // or a script or style tag 
 
     if (element !== children[i] && 
 
     !isNodeOneOf(children[i], ['SCRIPT', 'STYLE']) 
 
     ) 
 
     { 
 
     children[i].setAttribute('aria-hidden', isHidden); 
 
     } 
 
     } 
 

 
    walkDOM(element = element.parentNode); 
 
    } 
 
    } 
 

 
Object.defineProperty(HTMLElement.prototype, 'parentNode', 
 
         { get: getter }); 
 

 
walkDOM(document.getElementById("foo"));
<section> 
 
    <p> 
 
    <span> 
 
     <a> 
 
     <strong> 
 
      <span id="foo">Hi</span> 
 
     </strong> 
 
     </a> 
 
    </span> 
 
    </p> 
 
</section>

In dem obigen Zusammenhang getter ist:

Eine Funktion, die als Getter für die Eigenschaft dient, oder undefiniert, wenn kein Getter ist. Die Rückgabe der Funktion wird als Wert der Eigenschaft verwendet.

Referenzen

Verwandte Themen