8
votes

Préserver le comportement traditionnel d'ancrage avec NG-Inclure

Je ne construis pas une application à une seule page, mais plutôt un site "traditionnel" qui utilise angularjs dans des endroits. J'ai frappé le problème suivant (en utilisant 1.3.0-bêta.6):

Liens d'ancrage de travail: P>

<div ng-include="'test-include.html'"></div>


1 commentaires

Avez-vous défini?


5 Réponses :


6
votes

La raison est que l'angulaire remplace le comportement des balises HTML standard qui incluent code> également. Je ne sais pas quand ce changement s'est passé parce que l'angulaire v1.0.1 fonctionne bien avec cela.

Vous devez remplacer l'attribut href avec NgClick comme: p>

myApp.directive('a', function() {
  return {
    restrict: 'E', 
    link: function(scope, element) {
        element.attr('href', '#' + element.attr('href'));
    }
  };
});
p>

update: Strong> Je ne savais pas que vous ne voulez aucune modification dans HREF. Mais vous pouvez toujours obtenir le résultat souhaité en remplaçant la directive existante A code> comme: p> xxx pré>

démonstration: http://jsfiddle.net/hb7lu/3263/ p> p>


7 commentaires

De OP suit que le défilement fonctionne si aucun NG-Inclure a été utilisé, votre première hypothèse semble être incorrecte. De plus, op veut / ne peut pas faire de tours avec href , donc probablement la deuxième option ne fonctionnerait pas non plus.


Artitur, correct. J'ai une démo de travail utilisant exactement la technique suggérée par CODEF0RMER, mais refactore malheureusement tous les liens internes n'est pas une option (pas B / C c'est trop de travail, mais parce que nous allons alimenter des applications fournies par des parties extérieures de confiance et nous pouvons Il leur demande d'écrire toutes leurs ancrages de manière particulière, ce qu'ils ne pourraient pas être en mesure de tester à l'avance, etc.). Nous recherchons vraiment une manière non intrusive pour y accomplir. Merci cependant, codef0rmer.


ArturGrgrzesiak, merci de me corriger comme je me suis trompé dans mon hypothèse, mais @shacker, vous pouvez le mettre à jour à l'aide de directives personnalisées (voir la mise à jour ci-dessus).


Cette réponse presque fonctionne - la navigation se produit correctement, mais l'URL affichée change alors à / ## foo - comment ferais-je le montrer à une normale / # foo? Merci.


@shacker: convertit angulaire #foo à # / foo` - si cela vous convient, il vous convient simplement de regarder $ itinéraire événement et de mettre à jour le hachage.


Merci pour la directive Crétache CodeF0RMER. Fini par aller avec l'approche de la fonction plutôt que la directive, mais c'était un appel difficile. Merci beaucoup.


La solution de directive était parfaite pour mon client IE8. Merci!



2
votes

Ma compréhension est que l'utilisation de NG-Inclure implicitement dit angulaire que je veux utiliser le système de routes et remplacer le navigateur Comportement de liaison d'ancrage indigène. J'ai vu des recommandations pour travailler autour ceci en modifiant mes liens d'ancrage HTML vers # / # foo, mais je ne peux pas faire ça Pour d'autres raisons.

Système de routage est défini dans un module distinct ngroute , donc si vous ne l'avez pas injecté seul - et je suis sûr que vous ne l'avez pas fait - ce n'est pas accessible du tout.

Le problème est d'une manière ou d'une autre différente ici.

ng-Inclure dépend de: $ http , $ templatecache , $ anchorscroll , $ animer , $ sce . Ainsi, utilisez ng-include initier tous ces services.

Le candidat le plus naturel à enquêter serait $ anchorscroll . Le code de $ anchorscroll ne semble pas faire de mal, mais le service dépend de la fenêtre $ , Emplacement , $ rootscope . La ligne 616 de Emplacement dit: xxx

de sorte que la base href est définie sur '' , s'il est N'était pas de jeu avant.

Regardez maintenant Ici - de Baluscs Réponse :

comme pour utiliser des ancrages nommés comme, avec la balise vous déclarez essentiellement tous les liens relatifs par rapport à celui-ci, y compris les ancres nommées. Aucun des liens relatifs ne sont relatifs à la demande actuelle URI plus (comme cela se produirait sans le tag).

Comment atténuer le problème?

Je n'ai pas beaucoup de temps aujourd'hui, alors ne pouvez pas le tester moi-même, mais ce que j'essaierais de vérifier comme la première option consiste à se connecter à '$ EmplacementChangestart' événement et si la nouvelle URL est de #XXXXXXX Type Il suffit d'empêcher le comportement par défaut et du défilement avec $ anchorScroll méthodes natales à la place.

Mise à jour Je pense que ce code devrait faire le travail: xxx


8 commentaires

Artitur, j'ai ce presque travaillant comme indiqué dans cet essentiel, mais l'URL du navigateur ne reflète pas le changement. gist.github.com/shacker/11304251 J'ai essayé définir $ emplacement.path () et $ emplacement.url () à un nouvel emplacement après la navigation, mais pas de dés. Des idées?


@shacker Vous pouvez accéder directement à la route suivante et actuelle des arguments de rappel. Regardez la réponse mise à jour. (Je n'ai pas testé cependant)


OOH, Dynamite - Cela fonctionne bien, avec une petite exception: l'URL affichée va à / # / foo plutôt que / # foo. Y a-t-il un moyen de corriger cela? Très appréciée!


par exemple. Même si je change $ Emplacement.Hash (ELID) à $ Emplacement.Hash ("/ # bar"), l'URL affichée n'est pas affectée. Iotw $ emplacement.hash () semble avoir aucun effet, ce qui est la même chose que je prenne en charge.


HMM, pas de changement dans ce comportement après votre mise à jour. Toute autre idée? Merci.


@shacker Pourquoi ne pas utiliser de méthodes natales?


Merci un tas pour la solution et pour vos itérations, Artur. Appel difficile entre cette approche et l'approche de la directive, mais est allé avec cela à la fin. Ironiquement, angular semble avoir fait que le problème disparaisse dans les dernières bêtaies de 1,3, mais c'est un excellent pour la poche arrière.


La portée $. $ Sur () approche a fonctionné pour moi, mais cela provoque également une boucle d'événement infinie. Le navigateur (au moins chrome) reconnaît la boucle et la tue après quelques itérations, mais ce n'est toujours pas idéal. Est-ce que je fais quelque chose de mal? J'ai constaté que je devais appliquer .Substring (1) à elid car next.split () [1] retourné "/ foo", Alors peut-être que la question se trouve là-bas?



1
votes

Plutôt que d'appliquer l'application angulaire sur la page entière, vous pouvez isoler l'application aux endroits que vous souhaitez effectuer un NG-Inclure . Cela permettra des liens en dehors du champ d'application de la demande de conserver leur fonctionnalité normale, tout en permettant des liens dans l'application à la manière souhaitée.

Voir cette plunkr:

http://plnkr.co/edit/hob7ixrm39yzehaz0tfr?p=preview < / p>

Le Plunkr montre un lien à l'extérieur de l'application qui fonctionne comme normale et un lien de l'application qui est traité à l'aide d'une directive sur la A remplace pour restaurer la fonctionnalité normale. Le mode HTML5 est activé pour conserver des URL «Standard» (plutôt que 'HASHBANG' [SANS BANG!] URL).

Vous pouvez également exécuter l'ensemble de la page dans l'application, mais je pensais qu'il serait utile de démontrer comment isoler l'angulaire à certaines parties de la page dans tous les cas.


1 commentaires

Bon point mjtko. Je ne voudrais certainement pas avoir à aller d'avant en arrière entre le mode IN-APP-APP-APP-MODE (STYLE PHP) chaque fois qu'un lien d'ancrage se présente, mais oui, cela pourrait fonctionner techniquement.



2
votes

C'est la meilleure solution et fonctionne dans des versions récentes de Angular:

éteindre la manipulation de l'URL en angularjs


0 commentaires

2
votes

beaucoup en retard à la fête mais j'ai trouvé que l'ajout d'une cible simple = "_ soi" la corrige. xxx


0 commentaires