【问题标题】:Meteor Iron Router not working on certain linksMeteor Iron Router 在某些链接上不起作用
【发布时间】:2015-06-14 19:35:24
【问题描述】:

我有这样的路线:

Router.route('/box', function () {
    this.render('boxCanvasTpl');
},{
    name: 'box',
    layoutTemplate: 'appWrapperLoggedInTpl',
    waitOn: function() {
        console.log("Box route ran ok.");
        return [
            Meteor.subscribe('item_ownership_pub', function() {
                console.log("subscription 'item_ownership_pub' is ready.");
            }),
            Meteor.subscribe('my_items', function() {
                console.log("subscription 'my_items' is ready.");
            })
        ];
    }
});

...我正在单击模板中的链接,如下所示:

<a href="/box?box=123" class="box-num-items">My Link</a>

我收到“Box 路线运行正常”。消息,但由于某种原因页面无法导航到给定的 URL。我在渲染“boxCanvasTpl”时运行的函数中添加了 console.log 代码,但这些代码没有显示在浏览器控制台中。似乎中间有什么东西阻止了模板重新渲染,但我不能指望它 - 有什么想法吗?

【问题讨论】:

  • subscribe 的两个回调都去掉了还能用吗?
  • 这很难测试,因为包含上述链接的页面是我试图导航到的页面。这会是问题吗,即如果我在 /box?box=111 上并尝试导航到 /box?box=123 - 是不是“onRendered”功能不会重新运行?
  • 我对你在这里想要做什么感到有点困惑。您在 URL (?box=123) 中有参数,但是您没有任何代码可以使用 this.params - stackoverflow.com/questions/23050664/… 访问这些 URL 参数,是的,如果您在 Template.boxCanvasTpl.onRendered() 和它没有出现,这意味着模板没有被渲染(或重新渲染,在你的情况下)。哎呀,我讨厌讨厌讨厌 Stack Overflow cmets 中的格式......
  • @fuzzybabybunny 我在路由器之外使用 Router.current().params.query.box(在我的 Template.onRendered 函数中),但这与问题无关。
  • 啊,但它是相关的,因为 onRendered() 没有触发,因此你的参数没有被识别。

标签: meteor iron-router


【解决方案1】:

您需要了解 Iron Router 的一些属性。

假设用户当前已经在/boxes 上,并且有一个为该路径呈现的box 模板。如果你:

  • 点击链接&lt;a href="/boxes?box=123"&gt;Click Me&lt;/a&gt;

  • 点击链接&lt;a href="{{pathFor 'box'}}"&gt;Click Me&lt;/a&gt;

Iron Router 不会重新渲染模板,因为它已经存在于页面上。如果 box 模板恰好是已在您所在的页面上呈现并且也存在于您要导航到的页面上的部分模板,它也不会重新呈现模板。

由于它不会重新渲染,您在Template.box.onRendered 中的任何代码也不会再次运行。

这种行为在您的layoutheaderfooter 模板中最为常见。对于许多用户来说,这些模板用于网站的所有页面,无论路径如何。因为布局、页眉和页脚模板是在用户第一次访问网站时呈现的,所以如果用户决定使用相同的模板导航到网站的其他部分,它们将不会再被重新呈现,所以代码Template.layout/header/footer.onRendered 内部不会触发。

另请注意 - 即使响应式空格键助手更改了布局/页眉/页脚的物理外观,它也不符合实际的render,因此对模板的响应式更新不会触发onRendered 回调.

没有重新渲染让 Meteor 有“活泼”的感觉。

编辑

尝试以反应式、事件驱动的风格编写代码。尽量不要在渲染/重新渲染方面考虑太多。

  1. 你去/box
  2. 您单击/box?box=2342 的链接
  3. 在 Iron Router 中获取您的参数或查询

https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#route-parameters

  1. 在 Iron Router 中,使用参数或查询中的数据为模板设置 data context

  2. 在模板的.onRendered.events.helpers 回调中根据需要从数据上下文中获取内容。

  3. 根据需要设置会话变量,并在帮助程序中使用它们来对页面进行响应式更改,而无需重新呈现模板。还可以使用事件来触发对会话变量的更新,以再次触发对页面的响应式更改。

试试这个:

然后,转到 /test?BUNNIES=lalalala

查看控制台日志

test.html

<template name="test">

    {{myData}}

</template>

test.js

Template.test.helpers({

  myData: function() {
    console.log("data context accessed from test.helpers: ", this);
    console.log("this.BUNNIES accessed from test.helpers: ", this.BUNNIES);
    return this.BUNNIES;
  }

});

Template.test.onRendered(function() {

  console.log("data context accessed from test.onRendered: ", this.data);

});

Template.test.events({

  'click': function(){
    console.log("data accessed from test.events: ", this);
  }

});

router.js

Router.route('/test', function() {
  console.log("routed!");
  this.render('test');

}, {
  name: 'test',
  data: function(){
    //here I am setting the data context
    // for /test?BUNNIES=1234
    var query = this.params.query;
    console.log("query: ", query);

    return query;
  },
  waitOn: function() {
    console.log("waitOn is running (should see this message once for each subscription)");
    return [
      Meteor.subscribe('item_ownership_pub'),
      Meteor.subscribe('my_items')
    ];
  }
});

更简洁的路由器编写方式

Router.route('/test', {
  waitOn: function() {
    console.log("waitOn is running (should see this message once for each subscription");
    return [
      Meteor.subscribe('item_ownership_pub'),
      Meteor.subscribe('my_items')
    ];
  },
  data: function(){
    var query = this.params.query;
    console.log("query: ", query);
    return query;
  },
  action: function(){
    console.log("this will re-render if url params changed");
    this.render();
  }
})

【讨论】:

  • 谢谢你——我已经假设他是这样的。如果我有一个渲染页面的函数(使用 Blaze.renderWithData 等),我如何触发该函数从 Iron Router 运行?
  • 我不能让这个模板反应,因此我只想触发一个按需渲染模板的函数。
  • 我设置的路由器将在每次路径更改时重新渲染模板。 (即从/test?box=1234 到`/test?box=0987`)。是否选择使用响应式变量取决于您。
  • 我还添加了一种更简洁的方式来编写路由器函数,因为这样您可以直观地确定 Iron Router 执行操作的顺序(首先执行 waitOn,然后设置数据,最后执行渲染动作)
猜你喜欢
  • 2015-02-27
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2017-06-17
相关资源
最近更新 更多