我不是建立一个单页的应用程序,而是使用AngularJS的地方传统的网站。我已经打了以下问题(使用1.3.0-beta.6):
标准,工作锚链接:
< A HREF =#富>链接文字< / A>... [网页内容]<一个ID =foo的>< / A>< H1>标题< / H1>[更多内容]
这工作正常。现在我介绍一个模板部分地方:
<脚本类型=文/ NG-模板ID =测试include.html> < P>这文字是在一个单独的部分,并通过inlcuded NG-包括< / P>< / SCRIPT>
这是通过调用:
< DIV NG-包括=测试include.html'>< / DIV>
部分适当地包括,但锚链接不再起作用。点击链接文本现在改变显示的网址以 /#/富
,而不是 /#富
和页面位置不会改变。
我的理解是,使用 NG-包括
含蓄地告诉角度,我想使用的路由系统及覆盖浏览器的原生锚链接的行为。我见过的建议改变我的html锚链接#/#富
来解决这个问题,但我不能这样做,因为其他原因。
我不打算使用的路由系统 - 我只是想用 NG-包括
没有它与浏览器行为搞乱。这可能吗?
我的理解是,采用NG-包括隐含告诉角 我想使用的路由系统及覆盖浏览器的 本地锚链接的行为。我见过的建议来解决 这个改变我的html锚链接到#/#富,但我不能这样做 其他原因。
路由系统是在一个单独的模块定义 ngRoute
,所以如果你自己你没有注入它 - 我pretty确保你没有 - 它是无法访问的。
问题就在这里有些不同。
NG-包括
取决于: $ HTTP
, $ templateCache
, $ anchorScroll
, $动画
, $ SCE
。因此,请使用 NG-包括
启动所有这些服务。
最自然的候选者,调查将 $ anchorScroll
。 $ anchorScroll 似乎并没有做任何伤害,但该服务依赖于 $窗口
, $位置
, $ rootScope
。 $位置
的行616说:
baseHref = $ browser.baseHref()//如果基地[HREF]是不确定的,它默认为''
所以基本上基本href设置为,如果没有一套了。
现在看这里 - 从BalusC答案
至于使用命名锚一样,与标签 你基本上宣布所有相关链接相对于它, 包括命名锚。相对链接都不是相对于 当前请求的URI了(因为会发生不 标记)。
我没有太多的时间在今天,所以无法测试它自己,但我会尝试检查作为第一个选项是挂钩到的$ locationChangeStart事件,如果新的URL是 #XXXXXX 键入只是prevent默认的行为和滚动与
$ anchorScroll
本地方法来代替。
我觉得这$ C $ C应该做的工作:
$范围。在$($ locationChangeStart功能(事件,接下来,电流){ VAR埃尔,ELID; 如果(next.indexOf(#)-1个){ ELID = next.split(#)[1]; EL =的document.getElementById(ELID); 如果(EL){ // el.scrollIntoView();不认为我们需要它 window.location.hash =#+ ELID; 。事件preventDefault(); } }});
I am not building a single-page application, but rather a "traditional" site that uses AngularJS in places. I've hit the following problem (using 1.3.0-beta.6):
Standard, working anchor links:
<a href="#foo">Link text</a>
... [page content]
<a id="foo"></a>
<h1>Headline</h1>
[more content]
That works fine. Now I introduce a template partial somewhere:
<script type="text/ng-template" id="test-include.html">
<p>This text is in a separate partial and inlcuded via ng-include.</p>
</script>
which is invoked via:
<div ng-include="'test-include.html'"></div>
The partial is included properly, but the anchor link no longer works. Clicking on "Link text" now changes the displayed URL to /#/foo
rather than /#foo
and the page position does not change.
My understanding is that using ng-include
implicitly tells Angular that I want to use the routes system and overrides the browser's native anchor link behavior. I've seen recommendations to work around this by changing my html anchor links to #/#foo
, but I can't do that for other reasons.
I don't intend to use the routes system - I just want to use ng-include
without it messing with browser behavior. Is this possible?
My understanding is that using ng-include implicitly tells Angular that I want to use the routes system and overrides the browser's native anchor link behavior. I've seen recommendations to work around this by changing my html anchor links to #/#foo, but I can't do that for other reasons.
Routing system is defined in a separate module ngRoute
, so if you did not injected it on your own - and I am pretty sure you did not - it is not accessible at all.
The issue is somehow different here.
ng-include
depends on: $http
, $templateCache
, $anchorScroll
, $animate
, $sce
. So make use of ng-include
initiate all these services.
The most natural candidate to investigate would be $anchorScroll
. The code of $anchorScroll
does not seem to do any harm, but the service depends on $window
, $location
, $rootScope
. The line 616 of $location
says:
baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
So basically the base href is set to ''
, if it was no set before.
Now look HERE - from BalusC answer :
As to using named anchors like , with the tag you're basically declaring all relative links relative to it, including named anchors. None of the relative links are relative to the current request URI anymore (as would happen without the tag).
I do not have much time today, so cannot test it myself, but what I would try to check as the first option is to hook up to '$locationChangeStart' event and if the new url is of #xxxxxx
type just prevent the default behaviour and scroll with $anchorScroll
native methods instead.
I think this code should do the work:
$scope.$on("$locationChangeStart", function (event, next, current) {
var el, elId;
if (next.indexOf("#")>-1) {
elId = next.split("#")[1];
el = document.getElementById(elId);
if(el){
// el.scrollIntoView(); do not think we need it
window.location.hash = "#" + elId;
event.preventDefault();
}
}
});