我在主页上有一个我需要链接的登录框。登录框在html中有id="login
“,我有一个链接就像这个<li><a href="#login">Login</a></li>
所以点击它会带我到登录div但是当我点击刷新或直接转到锚点的链接我得到Uncaught Error: No route matched the URL 'login'
任何人都有任何想法如何在Ember完成这个简单的任务?感谢。
更新
以下是我的代码的样子:
导航
<ul class="nav navbar-nav pull-right">
<li><a href="#login">Signup</a></li>
<li>{{#linkTo 'about'}}About{{/linkTo}}</li>
</ul>
以及我在页面下方的某处
<section id="login">
-- some content
</section>
答案 0 :(得分:15)
基于alexspellers原始JSFiddle,可以在此处找到完整的演示:http://jsfiddle.net/E3xPh/
在Router
中,添加对查询参数的支持
App.Router.map ->
@resource 'index', path: '/', queryParams: ['anchor']
使用您选择的Route
,在anchor
方法中为setupController
查询参数设置属性。
App.IndexRoute = Em.Route.extend
setupController: (controller, context, queryParams) ->
controller.set 'anchorLocation', queryParams.anchor
最后在您的Controller
中为anchorLocation
财产制作观察员。
App.IndexController = Em.ArrayController.extend
showAnchor: (->
$elem = $(@anchorLocation)
$scrollTo = $('body').scrollTop($elem.offset().top)
).observes 'anchorLocation'
现在,您可以在模板中使用以下代码滚动到某个锚点,或将浏览器指向/#/?anchor=#login
。
{{#linkTo anchor='#login'}}Show login{{/linkTo}}
根据您在第一个答案的评论中所写的内容,可能的答案。在这里把简单的东西搞得一团糟。
单击“索引”链接将转到IndexRoute并将您滚动到登录框,但URL未反映此更改,并且键入#login也不起作用。
App.ApplicationRoute = Ember.Route.extend({
events: {
goToLink: function(item, anchor) {
var $elem = $(anchor);
var $scrollTo = $('body').scrollTop($elem.offset().top);
this.transitionToRoute(item.route).then($scrollTo); //.transitionTo is depricated
}
}
});
当您想要滚动到锚点时,您将在模板中使用goToLink,而不是使用linkTo。
<ul>
<li><a href="#/" {{action goToLink "index" "#login"}}>Index</a></li>
<li>{{#linkTo about}}About{{/linkTo}}</li>
<li>{{#linkTo contact}}Contact{{/linkTo}}</li>
</ul>
答案 1 :(得分:8)
问题在于Ember使用URL中的哈希部分来存储应用程序的当前状态。我自发地看到了两种可能的解决方案。
1 - * 不要让Ember使用您网址的哈希部分。 *因此请使用Ember的 HTML5历史记录位置实施。这将导致yourdomain.com/users/1/
之类的网址没有#
。
App.Router.reopen({
location: 'history'
});
2 - 不要使用这种技术。而是使用jQuery 来滚动到相关部分。这看起来像这样:
<ul class="nav navbar-nav pull-right">
<li><a {{action jumpToLogin}}>Signup</a></li>
<li>{{#linkTo 'about'}}About{{/linkTo}}</li>
</ul>
并在相应的视图中:
App.YourView = Ember.View.extend({
jumpToLogin : function(){
$('html, body').animate({
scrollTop: $("#login").offset().top
}, 2000);
}
});
对于这个小功能,这似乎有很多代码,但我想这是一个更好的用户体验吧? 实际上,您可以通过将此逻辑提取到mixin 来改进此方法,因此您不必一遍又一遍地重复它:
App.ScrollToMixin = Ember.Mixin.create({
scrollDuration : 2000, //default
scrollTo : function(selector){
$('html, body').animate({
scrollTop: $(selector).offset().top
}, this.get("scrollDuration");
)
});
// mix it into your View
App.YourView = Ember.View.extend(App.ScrollToMixin, {});
并在模板中使用它:
<ul class="nav navbar-nav pull-right">
<li><a {{action scrollTo "login"}}>Signup</a></li>
<li>{{#linkTo 'about'}}About{{/linkTo}}</li>
</ul>
PS:我没有使用mixin测试代码。我并不完全确定String“login”会像那样传递给动作处理程序。所以你必须测试: - )
答案 2 :(得分:5)
我使用了一个组件,它也可以通过动作扩展为支持查询参数。
var ScrollToComponent = Ember.Component.extend({
tagName: 'a',
anchor: '',
scrollTo: function () {
var anchor = this.get('anchor'),
$el = Ember.$(anchor);
if ($el) {
Ember.$('body').scrollTop($el.offset().top);
}
}.on('click')
});
这就是你如何使用它:
{{#scroll-to anchor=anchor}}Jump To Anchor{{/scroll-to}}
anchor
为#my-id
。
修改强>
的ember-cli插件答案 3 :(得分:1)
我使用kroovy的答案中的简单行动方法在Ember工作。
由于Ember改变了它的API,我不得不稍微改变kroovys的方法。
有两件事发生了变化:
以下是我在Ember版本1.7.0中使用它的方法
Ember Handlebars-Template new.hbs
{{!-- Navigation --}}
<ul>
<li {{action 'goToLink' "new" "#part1"}}>Part 1</li>
<li {{action 'goToLink' "new" "#part2"}}>Part 2</li>
</ul>
{{!-- content --}}
<div id="part1" class="row">...</div>
<div id="part2" class="row">...</div>
Ember App.Controller NewController.js
App.NewController = Ember.ArrayController.extend({
actions: {
goToLink: function(item, anchor) {
console.log('NewController > goToLink');
var $elem = $(anchor);
var $scrollTo = $('body').scrollTop($elem.offset().top);
this.transitionToRoute(item.route).then( $scrollTo);
}
}
});
答案 4 :(得分:1)
以前大多数答案的问题是,如果在点击其中带有“href hash / fragment / id”的“链接”时路由没有改变,那么ember路由器将不会触发执行所需的钩子大多数以前的解决方案。
这在具有多个“标题”的页面中很明显,您希望允许用户从“导航/索引或链接列表”跳转到页面的相关部分(例如服务条款或页面) 。
在这些情况下,ember要求你“选择进入完全转换”,这样路由器就会触发它的挂钩,即使路由没有改变但查询参数有。有关详细信息,请参阅"opting into a full transition"。
注意:使用此“opt in”时将触发的唯一记录的挂钩是模型挂钩。
我认为这种“完全转换”选择仅用于在查询参数上刷新模型时使用,例如排序或过滤。
不可否认,这看起来有点像黑客,但上面的“选择加入”可用于滚动到我们的div / anchor标签。在将来,选择加入也可以解雇其他更合适的钩子(setupController特别适合)。
此外,如果有人在谷歌上搜索。我也尝试在路线上使用“willTransition”和“didTransition”动作。虽然他们在从其他路线转换时确实被解雇了,但是当他们从同一条路线转换到自身时,它们也无法触发。
最后,对某些人来说应该是显而易见的(但最初并不适合我),为了让浏览器滚动到有问题的ID,需要完全加载dom。所以我们必须在Ember.run.schedule('afterRender',
回调中执行滚动。
仅供参考我现在正在使用最新的ember-cli,ember.js和ember-data:
应用程序/ router.js
this.route('about', {
queryParams: ['anchor']
});
路由/ about.js
import Ember from 'ember';
export default Ember.Route.extend({
queryParams: {
anchor: {
refreshModel: true
}
},
model: function(params) {
var aboutController = this.controllerFor('about');
aboutController.set('anchorLocation', params.anchor);
}
});
应用程序/控制器/ about.js
import Ember from "ember";
export default Ember.Controller.extend({
queryParams: ['anchor'],
anchor: '',
showAnchor: function() {
var _this = this;
Ember.run.schedule('afterRender', function scrollToAnchor(){
var elem = Ember.$(_this.anchorLocation);
elem.get(0).scrollIntoView(true);
});
}.observes('anchorLocation'),
});
应用程序/模板/ footer.js
<ul>
<li>
{{#link-to "about" (query-params anchor='#contact')}}Contact{{/link-to}}
</li>
<li>
{{#link-to "about" (query-params anchor='#support')}}Support{{/link-to}}
</li>
<li>
{{#link-to "about" (query-params anchor='#team')}}Team{{/link-to}}
</li>
</ul>
答案 5 :(得分:0)
我的问题是,如果我从另一个页面点击目标链接,它将转到目标但不向下滚动到页面的正确部分。几个小时后,这是我的修复:
注意:我正在使用ember-cli
,emblem
和ember 1.8
navigation bar
(application.emblem
)中的链接
li
a#concept-link click=jumpToConcept
| Le Concept
然后,如果我已经在页面上,我只需向上滚动。如果我还没有在页面上,那么我将使用查询参数concept=true
action
中的 application controller
scrollToConcept: function() {
Ember.$(document).ready(
Ember.$('html, body').animate({
scrollTop: Ember.$("#concept").offset().top
}, 750)
)
},
//allow clicking of link with specific id to go to that part of page
jumpToConcept : function(){
if (this.get('currentPath') === 'index') {
this.send('scrollToConcept');
} else {
this.transitionToRoute('index', { queryParams: {concept: true}});
}
}
在index controller
中然后添加concept query params
export default Ember.Controller.extend(
queryParams: ['concept'],
concept: null
}
然后我在scrollToConcept
(我刚去过的页面)中添加了index view
事件,该事件侦听页面加载并检查concept queryParam
。如果concept=true
我滚动到页面的概念部分。
index view
scrollToConcept: function() {
if (this.controller.get('concept') === 'true') {
Ember.$('html, body').animate({
scrollTop: Ember.$("#concept").offset().top
}, 750);
}
}.on('didInsertElement')
然后对于普通index links
,我添加了一个设置concept=null
的操作,以便concept query param
不会显示在网址中。
链接
nav bar
然后在a click=goToIndex
h3 id={logoClass} Happy Dining
我转到application controller
,将index route
设置为null(因此它不会显示在网址中)并滚动到顶部(只是加入它)在页面上较低)
concept query param
希望将来帮助人们!!!
答案 6 :(得分:0)
如果有人正在尝试使用Ember 3解决此问题,那么我有解决方案。它使用了与其他人提到的相同的queryParams方法,但是我无法在控制器上进行任何操作。我发现可行的唯一方法是使用route + jQuery.ready函数。
// route/application.js
import Route from '@ember/routing/route';
import $ from 'jquery';
export default Route.extend({
queryParams: {
anchor: null
},
setupController: function(controller, context, params) {
let anchor = params.queryParams.anchor;
// On ready, find the anchor offset and go there
$().ready(function() {
let anchorOffset = $("#" + anchor).offset().top
window.scrollTo(0, anchorOffset);
});
}
});
然后在模板中,照常使用您的queryParams:
{{#link-to "path.to.page" (query-params anchor="my-anchor")}}My Link{{/link-to}}
这里唯一的问题是它每次都会重新加载页面,但除此之外似乎还行得通-希望它能对某人有所帮助。