使用 Ember.js 的 Hashbang URL

Posted

技术标签:

【中文标题】使用 Ember.js 的 Hashbang URL【英文标题】:Hashbang URLs using Ember.js 【发布时间】:2013-02-02 11:06:15 【问题描述】:

我正在尝试将我的 Router 设置为使用“hashbang”网址 (#!)。

我试过了,但显然它不起作用:

App.Router.map(function() 
    this.route("index",  path: "!/" );
    this.route("otherState",  path: "!/otherState" );
);

这可以在 Ember 中实现吗?

【问题讨论】:

我设法通过覆盖Ember.HashLocation 属性来添加一些'!'到几个字符串。我不完全确定这是否最终会破坏任何东西。如果没有人发布更合法的方法,我将添加我的代码作为答案。 【参考方案1】:

扩展 Ember.HashLocation 将是可行的方法。

对于干净的实现,您可以执行以下操作。

Ember.Location.registerImplementation('hashbang', Ember.HashLocation.extend(
  // overwrite what you need, for example:
  formatURL: function(url) 
    return '#!' + url;
  
  // you'll also need to overwrite setURL, getURL, onUpdateURL...
)

然后指示您的 App Router 使用您的自定义实现进行位置管理:

App.Router.reopen(
  location: 'hashbang'
)

【讨论】:

好答案。我没有在我的解决方案中使用registerImplementation。这绝对使它更干净。我编辑了您的答案以包含完整的代码以使其正常工作,因为除了formatURL 中的更改之外,还需要进行其他几项更改 由于某种原因,我对您的回答的编辑被拒绝了。不知道这笔交易是什么。无论如何,我只是用代码发布了自己的答案,以完全实现 hashbang URL 功能。【参考方案2】:

Teddy Zeenny 的回答大部分是正确的,registerImplementation 似乎是实现这一点的一种干净的方式。我试图只编辑他的答案以使其完全回答问题,但我的编辑被拒绝了。

这里是让 Ember 使用 hashbang URL 的完整代码:

(function() 

var get = Ember.get, set = Ember.set;

Ember.Location.registerImplementation('hashbang', Ember.HashLocation.extend( 

    getURL: function() 
        return get(this, 'location').hash.substr(2);
    ,

    setURL: function(path) 
        get(this, 'location').hash = "!"+path;
        set(this, 'lastSetURL', "!"+path);
    ,

    onUpdateURL: function(callback) 
        var self = this;
        var guid = Ember.guidFor(this);

        Ember.$(window).bind('hashchange.ember-location-'+guid, function() 
                Ember.run(function() 
                    var path = location.hash.substr(2);
                    if (get(self, 'lastSetURL') === path)  return; 

                    set(self, 'lastSetURL', null);

                    callback(location.hash.substr(2));
                );
        );
    ,

    formatURL: function(url) 
        return '#!'+url;
    

));

)();

创建应用后,您需要更改路由器以利用“hashbang”位置实现:

App.Router.reopen(
    location: 'hashbang'
)

【讨论】:

只有几个 cmets: - 最好重新打开 App.Router 而不是 Ember.Router (所以你保持 ember 默认值干净,尤其是在测试时) - 你不需要覆盖initwillDestroy 因为你扩展了HashLocation,所以这些函数会被继承,代码会更简单。 谢谢。我改变了你说的。 此方法运行良好,但在去年余烬中抛出了弃用消息;在不使用不推荐使用的代码的情况下,我们必须做什么才能使用它? 以防万一有人不知道,Google 还可以抓取使用 html5 pushState 而不是 hash-bang 方法的网站。这是马口中的:youtube.com/watch?v=yiAF9VdvRPw 这是使用它的 Ember 文档:emberjs.com/api/classes/Ember.Location.html#toc_historylocation

以上是关于使用 Ember.js 的 Hashbang URL的主要内容,如果未能解决你的问题,请参考以下文章

toastr 和 ember.js

如何使用 Ember.js 和 ember-data 创建新记录?

Ember.js:在服务的把手中使用计算属性

Ember.js 和玩!框架身份验证最佳实践

使用 Ember.js,如何在渲染视图后运行一些 JS?

Ember.js 中的视图与组件