Emberjs莫代尔作为一条路线

时间:2015-01-14 12:24:02

标签: ember.js ember-router

我试图弄清楚如何将路线转换为模态,这样您就可以通过任何其他路线导航到它,同时保留底层(上一个)模板。

例如:

http://example.com/site/index转到index.hbs

http://example.com/site/page2转到page2.hbs

如果用户来自另一个域(重新开始),

http://example.com/site/article/1234会转到article.hbs

如果用户选择任何其他路线,那么http://example.com/site/article/1234会在“文章模式”商店内打开article.hbs。

这是router.js

Market.Router.map(function() {
this.route('index', { path: '/' });
this.route('start', { path: 'start' });
this.route('article', { path: 'article/:article_id' });
this.route('404', { path: '*:' });
});

这里是application.hbs

<div class="main-container">{{outlet}}</div>
{{outlet "article-modal"}}

这里是article.js route 备选案例#1

Em.Route.extend({
beforeModel: function(transition, queryParams) {
    if(!Em.isEmpty(this.controllerFor('application').get('currentRouteName'))) {
        this.render('article', {
    into: 'application',
    outlet: 'article-modal'
  });
        return Em.RSVP.reject('ARTICLE-MODAL');
    }
},

model: function(params) {
    return this.store.find('article', params.id);
},

actions: {
error: function(reason) {
        if(Em.isEqual(reason, 'ARTICLE-MODAL')) { // ARTICLE-MODAL errors are acceptable/consumed
            //
            return false;
        }
        return true;
}
}
});

这里是article.js route 备选案例#2

Em.Route.extend({

renderTemplate: function() {
    if(!Em.isEmpty(this.controllerFor('application').get('currentRouteName'))) {
        this.render({into: 'index', outlet: 'article-modal'});
    } else {
        this.render({into: 'application'});
    }

},

model: function(params) {
    return this.store.find('product', params.id);
},
});

情况#1的问题是浏览器地址栏不反映当前路线。如果用户从索引路径转到文章路径,浏览器地址栏仍会显示/ index ..所以如果他按下后退按钮应用程序中断。

情况#2的问题是它丢弃了index.hbs的内容,因为文章路由没有嵌套。

Ember甚至可以提供这样的功能吗?

谢谢:)

2 个答案:

答案 0 :(得分:1)

编辑:重新阅读OP的问题并意识到我没有理解他的问题,所以我创建了一个新的答案(https://stackoverflow.com/a/27948611/1010074),概述了我在实验后提出的另一种方法有事。

选项1:Ember建议的处理模式的方法

Ember网站上有一本&#34;食谱&#34;他们建议如何处理模态对话框: http://emberjs.com/guides/cookbook/user_interface_and_interaction/using_modal_dialogs/

基本上,您将在打开模态的路线中创建一个动作:

App.ApplicationRoute = Ember.Route.extend({
  actions: {
    openArticleModal: function(article) {
      return this.render(article, {
        into: 'application',
        outlet: 'modal',
        controller: this.controllerFor("article")
      });
    }
  }
});

然后从您的控制器/其他路线拨打this.send("openArticleModal", article),或者您可以在模板中执行类似<button {{action "openArticleModal" article}}>View Artice</button>的操作。

本质上,此方法将模态从路由状态中取出,这意味着模态不会被URL绑定,但是如果您需要能够从应用程序中的任何位置打开模态而不是取消渲染模式目前的路线,那么它是你的几个选择之一。

选项2:如果您需要可以从任何地方打开的URL绑定模式

对于当前项目,我使用查询参数完成了适用于此用例的操作。对我来说,这感觉有点hacky,但是到目前为止我的测试中它运行得相当好(社区中的其他人 - 如果你对此有意见,请告诉我)。基本上,它看起来像这样:

App.ApplicationController = Ember.Controller.extend({
   queryParams: ["articleId"],
   articleId: null, 

   article: function() {
      if(!this.get("articleId") return null;
      return this.get("store").find("article", this.get("articleId"));
   }
});

在application.hbs中:

{{#if article.isFulfilled}}
    {{render "articleModal" article.content}}
{{/if}}

然后我可以使用普通的{{link-to}}助手并链接到查询参数:

{{#link-to (query-params articleId=article.id)}}View Article{{/link-to}}

这有效,但我对此解决方案并不完全满意。稍微清洁的东西可能是使用插座{{outlet "article-modal"}}并将应用程序路径渲染到其中,但可能需要更多的LOC。

选项3:如果仅从一条路线打开模态

您可以将模态打开的路径设置为模态路径的父级。像这样:

Market.Router.map(function() {
    this.resource('articles', { path: '/articles' }, function() {
        this.route('modal', { path: '/:article_id' }); 
    });
});

如果您的模态只能打开&#34;这很有效。从一条路线内。在上面的示例中,模式将始终在文章路径的顶部打开,如果您从应用程序中的任何其他位置链接到模式路径,则文章路径将呈现在模式下方。只要确保&#34;关闭&#34;你的模态的动作将你转移到模态路线之外,因此用户无法关闭你的模态,但仍然在模态路线上。

答案 1 :(得分:1)

这是我对这个问题的第二个答案。我的原始答案(https://stackoverflow.com/a/27947475/1010074)并没有直接回答OP的问题,但是,我在答案中概述了另外三种处理Ember中的模态的方法,并将其留在那里,以防它出现在&#39;对其他人有帮助。

解决方案:使用相同路径定义多条路线

虽然Ember通常不允许您定义两条使用相同路径的路由,但实际上您可以拥有嵌套路由和具有相同有效路径的非嵌套路由,而Ember可以正常使用它。根据我原来的答案建立选项3,我已经汇总了一个我认为适合你的概念证明。这是一个JS小提琴:http://jsfiddle.net/6Evrq/320/

基本上,你可以使用类似这样的路由器:

App.Router.map(function () {
    this. resource("index", {path: "/"}, function(){ 
        this.route("articleModal", {path: "/article"});    
    });
    this.route("article", {path: "/article"});
});

在您的模板中,链接到index.articleModal路线:

{{#link-to "index.articleModal"}}View article!{{/link-to}}

由于articleModal内部index呈现,您的index路由未呈现。由于网址路径更改为/article,因此重新加载网页会将您转到常规Article路线。

免责声明:我不确定这是否正在利用当前Ember中的错误,因此这里的里程可能会有所不同。