Wie setze ich einen scrollspy in angular.js richtig um?

8

Hat jemand irgendwelche Gedanken darüber, wie man eine Scrollspy in einer eckigen App am besten implementieren kann? Ich begann mit der Implementierung von Twitter Bootstrap , aber ich habe Probleme, einen guten Ort für die Initialisierung zu finden (und noch wichtiger Aktualisieren nach DOM Änderungen) das Plugin.

Grundsätzlich führt mein Controller eine Async-Anfrage nach Daten durch, wenn er geladen wird, und kann das DOM nicht vollständig rendern, bis die Anfrage zurückkommt. Wenn das DOM vollständig gerendert ist, muss das scrollspy-Plugin aktualisiert werden. Im Moment habe ich einen Controller, der ein Ereignis auf seinen Bereich sendet, sobald die benötigten Daten empfangen wurden, und ich habe eine Anweisung, die dieses Ereignis aufgreift. Ich mag diese Lösung aus zwei Gründen nicht wirklich

  1. Es fühlt sich einfach hacky.

  2. Wenn ich das scrollspy-Plugin nach dem Empfang dieses Ereignisses aktualisiere, ist es immer noch zu früh, da das DOM erst später im Zyklus aktualisiert wird. Ich habe versucht, evalAsync, aber am Ende musste ich ein Timeout verwenden und hoffe nur das DOM rendert schnell genug.

Ich habe mir die Quelle für das Bootstrap-Plugin angeschaut scheint ziemlich geradlinig, um dies von Grund auf neu zu implementieren. Das Problem dabei war, dass ich, als ich versuchte, eine Direktive dafür zu erstellen, anscheinend keine Scroll-Ereignisse von dem Element abonnieren konnte, das ich in der Link-Funktion erhalten hatte.

Hat jemand eine gute Lösung für so etwas gefunden oder hat jemand irgendwelche Vorschläge? Ich bin in keiner Weise an die Bootstrap-Implementierung gebunden, denn im Moment ist das einzige, was ich auf Bootstrap habe, das Scrollspy-Plugin, das ich gerade hinzugefügt habe.

    
ivarni 04.07.2013, 12:29
quelle

4 Antworten

11

Es gibt einige Herausforderungen bei der Verwendung von Scrollspy in Angular (wahrscheinlich, warum AngularUI Scrollspy ab August 2013 immer noch nicht enthält).

Sie müssen den scrollspy jederzeit aktualisieren, wenn Sie Änderungen am DOM-Inhalt vornehmen.

Dies kann geschehen, indem $ das Element beobachtet und ein Timeout für den scrollspy-Aufruf ('refresh') festlegt.

Sie müssen auch das Standardverhalten der Navigationselemente überschreiben, wenn Sie die Navigationselemente verwenden möchten, um durch den scrollbaren Bereich zu navigieren.

Dies kann erreicht werden, indem preventDefault für die Ankerelemente verwendet wird, um die Navigation zu verhindern, und indem eine scrollTo-Funktion an den ng-Klick angehängt wird.

Ich habe ein funktionierendes Beispiel auf Plunker geworfen: Ссылка

    
Ryan Kimber 06.08.2013, 12:46
quelle
18

Alexander Hill hat einen Beitrag verfasst, der eine AngularJS-Implementierung von Bootstrap's ScrollSpy beschreibt: Ссылка

Ich habe seinen CoffeeScript-Code in JavaScript übersetzt, ein paar Bugs behoben, ein paar Sicherheitschecks hinzugefügt und eine zusätzliche Funktion hinzugefügt. Hier ist der Code:

%Vor%

Ein HTML-Code aus Alexanders Blogpost, der zeigt, wie die Richtlinie implementiert wird:

%Vor%     
Evil Closet Monkey 24.02.2014 18:55
quelle
4

Ich habe ein Projekt auf GitHub gefunden, das ScrollSpy, animierte scrollTo und Scroll-Ereignisse hinzufügt.

Ссылка

Hier können Sie sich die Live-Demo ansehen und hier ist das beispielquelle

Sie können Bower verwenden, um es zu installieren

%Vor%     
kaelle 14.01.2015 05:07
quelle
1

Ich benutze Original Bootstrap scrollspy. Nav-Links sind wie eine Seite ohne Anuglars ngRoute. Dann setze ngRoute für diese Seite mit der Option reloadOnSearch: false Für das Scrollen verwende ich Angular build-in # support - wenn URL looklikes http://host/#/path#anchor dann lädt ngRoute die Seite für den angegebenen '/ Pfad 'und scrollt zum angegebenen' Anker '.

Sie sehen es nicht, ohne reloadOnSearch: Falsche Seite wird jedes Mal geladen und im Moment des Scrollens wird das Element mit ID, wie im Anker angegeben, noch nicht gerendert. Zum Lösen des Problems des anfänglichen Scrollens, um nach dem anfänglichen Laden der Seite zu verankern und Rendern wird viel geschrieben.

Das letzte Element meiner Lösung besteht darin, eine eigene Direktive zu schreiben, die auf jeder Nav-Verknüpfung platziert ist - sie stoppt die Klick-Propagierung, verhindert Standardaktionen und setzt den Seitenanker auf Angular-Anforderungen. Wenn zum Beispiel die Seiten-URL http://host/#/path ist und die Link-Verknüpfung href="# some-id" lautet, wird durch die Anweisung die neue URL http://host/#/path#some-id

erstellt     
Todor Kisov 20.09.2015 15:54
quelle