Meteor JS铁路:每当路由更改时应用CSS更改

5

我的应用中有主页、联系页面和其他几个与产品相关的页面。

目标是仅将背景图应用于特定路由:/homepage/contact。如果用户从任一路由导航离开,则应用一些 CSS 更改。

我现在正在使用主页上的帮助程序来实现这个目标,如下所示:

Template.homepage.rendered = function () {

    var route = Router.current();

    if ( route.path == '/' ) {

        document.body.className = "showBackgroundImage";

    }
};

部分胜利,因为这将激活CSS,但我需要在路由更改时停用。我还尝试了以下方式在我的router.js中:

this.route('homepage', {
    path: '/', 
    onAfterAction: function  (argument) {
       // add a class name to body
       document.body.className = "showBackgroundImage";
    }
  });

在后台标准中,CSS是指:

.showBackgroundImage { 
  background: url(bgImage.jpg) no-repeat center center fixed; 
}
3个回答

6
这很容易通过使用iron:router布局并通过路由为每个页面应用不同的类来完成。
首先,您需要定义一个主要布局,例如:
<template name="mainLayout">
  <!-- optional navbar yield -->
  {{> yield region="navbar"}}
  <div class="{{currentRouteName}}-page">
    {{> yield}}
  </div>
  <!-- optional footer yield -->
  {{> yield region="footer"}}
</template>

currentRouteName助手应该类似于:

UI.registerHelper("currentRouteName",function(){
  return Router.current()?Router.current().route.getName():"";
});

我建议将一个 RouteController 关联到你的主布局中,它将作为所有 RouteController 的基类。

MainController=RouteController.extend({
  layoutTemplate:"mainLayout",
  // yield navbar and footer templates to navbar and footer regions respectively
  yieldTemplates:{
    "navbar":{
      to:"navbar"
    },
    "footer":{
      to:"footer"
    }
  }
});

接下来,您需要确保您的路由使用从MainController派生的控制器。

HomeController=MainController.extend({
  template:"home"
});

Router.map(function(){
  this.route("home",{
    path:"/",
    // optional, by default iron:router is smart enough to guess the controller name,
    // by camel-casing the route name and appending "Controller"
    controller:"HomeController"
  });
});

现在你的主页路由页面被一个带有“home-page”类的div所包围,因此你可以使用纯CSS(或更好地,使用LESS)来进行样式设计:

.home-page{
  /* your css goes here */
}

如果您定义了其他路由,这将无缝工作,只需继承MainController,您就会自动拥有一个带有路由名称页类的页面。
当然,您可以为多个页面使用相同的样式,只需在CSS中指定即可。
.home-page, .contact-page{
  /* your css goes here */
}

使用布局可以做出非常棒的效果,我强烈鼓励您使用它们。


2
补充此方法:有时您需要更改特定布局的body类才能使其正常工作。为此,请使用该布局的“rendered”和“destroyed”回调,例如:Template.layout.rendered = function() {$('body').addClass('layoutBody')}; 然后 Template.layout.destroyed = function() {$('body').removeClass('layoutBody')}; - Hubert OG
从Iron Router 1.0开始(或许更早),使用Router.current().route.getName()来获取当前路由名称(注意从route.name变为了route.getName())。 - Isaac Gregson
感谢您注意到已弃用的代码,我已更新我的答案。为了进一步解释这一点,route现在是function而不是普通的object,在JS中,name是包含function名称的function的默认属性,因此需要新的getName() getter。 - saimeunt

3

我曾使用 iron-routerjQuery 完成了这个任务。以下是我的做法。

/**
 * Add a background image for certain routes.
 */
var setBackground = function () {
  var route = this.route.name;
  var routes = ['homepage', 'contact'];

  if (_.contains(routes, route)) {
    $('body').addClass('showBackgroundImage');
  } else {
    $('body').removeClass('showBackgroundImage');
  }
};

Router.onBeforeAction(setBackground);

1

使用 Meteor 1.2iron-router,这是对我来说非常容易的有效方法:

Router.onBeforeAction(function() {
  $('body').addClass(this.route.options.template);
  this.next();
});

就这样了!

这将从您使用的模板中获取名称并将其分配给主体。

多么容易和方便啊!!

如果您想分配特定的名称而不是模板名称,请用 this.route.getName() 替换 this.route.options.template 并为路由指定一个名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接