UI助手功能在Meteor中没有订阅数据

时间:2015-07-31 05:16:09

标签: meteor meteor-helper meteor-publications

我对Meteor很新。

我有一个模板帮助函数,它需要处理我从服务器端发布的数据。页面加载时,以下配置文件的值为undefined。但在那之后,当我从浏览器的控制台执行相同的代码片段时,它的工作正常。据我所知,模板助手在数据发布之前正在执行。我怎么能等到发布数据才能运行UI助手?

以下是相关代码。

辅助功能

Template.header.helpers({  
  me: function() {
    var user = Meteor.users.findOne(Meteor.userId());
    if (user) {
      return Profiles.findOne({
        spid: user.profile.spid
     });
    }

    return null;
  }
});

HTML模板

<template name="header">
  <header class="ui fixed inverted menu">
    {{> thumb user=me}}
  </header>
</template>

缩略图模板

<template name="thumb">
  {{#with user}}
  <div class="thumb">
    <div class="text" style="background-color:{{color}}">
      {{initials name}}
    </div>
    <div class="pic" style="background-image:url('{{pic}}')"></div>
  </div>
  {{/with}}
</template>

出版物

Meteor.publish('profiles', function() {
  return Profiles.all();
});

Meteor.publish('departments', function() {
  return Departments.all();
});

Meteor.publish('requestServiceIds', function() {
  return Requests.getServiceIds();
});

Meteor.publish('relevantServices', function() {
  return Services.getRelevant(this.userId, 5);
});

路由器

Router.configure({
  layoutTemplate: 'main',
  waitOn: function() {
    Deps.autorun(function() {
      Meteor.subscribe('profiles', Partitioner.group());
      Meteor.subscribe('departments', Partitioner.group());
    });
  }
});

Router.onBeforeAction(function() {
  if (this.route.getName() === 'not-authorized') return this.next();

  if (!Meteor.userId() || !Cookie.get('TKN')) {
    this.render('login');
  } else {
    this.next();
  }
});

Router.route('/', {
  name: 'home',
  waitOn: function() {
    Deps.autorun(function() {
      Meteor.subscribe('requestServiceIds', Partitioner.group());
      Meteor.subscribe('relevantServices', Partitioner.group());
    });
  }
});

---

更新1

我稍微更新了路由器。但它似乎没有任何区别。

Router.configure({
  layoutTemplate: 'main',
  waitOn: function() {
    // Deps.autorun(function() {
    //   Meteor.subscribe('profiles', Partitioner.group());
    //   Meteor.subscribe('departments', Partitioner.group());
    // });

    return [
      Meteor.subscribe('profiles', Partitioner.group()),
      Meteor.subscribe('departments', Partitioner.group())
    ];
  }
});

Router.route('/', {
  name: 'home',
  waitOn: function() {
    // Deps.autorun(function() {
    //   Meteor.subscribe('requestServiceIds', Partitioner.group());
    //   Meteor.subscribe('relevantServices', Partitioner.group());
    // });

    return [
      Meteor.subscribe('requestServiceIds', Partitioner.group()),
      Meteor.subscribe('relevantServices', Partitioner.group())
    ];
  }
});

1 个答案:

答案 0 :(得分:0)

创建一个哑本加载模板,例如这个(使用font awesome):

<template name="loading">
    <div class="loading">
        <i class="fa fa-circle-o-notch fa-4x fa-spin"></i>
    </div>
</template>

尝试用以下内容替换Router.configure()部分:

Router.configure({
  layoutTemplate: 'main',
  action: function() {
        if(this.isReady()) { this.render(); } else {this.render("loading");}
    },
    isReady: function() {
        var subs = [
            Meteor.subscribe('profiles', Partitioner.group());
            Meteor.subscribe('departments', Partitioner.group());
        ];
        var ready = true;
        _.each(subs, function(sub) {
            if(!sub.ready())
            ready = false;
        });
        return ready;
    },

    data: function() {
        return {
            params: this.params || {},
            profiles: Profiles.find(),
            departments: Departments.find()
        };
    }
  }
});

我想这可以用waitOn来实现,但由于你的方式不起作用,我给你一个我每天使用的工作方法。代码灵感来自meteor Kitchen生成的代码。

回答你的意见:

关于Action没有被触发,可能是因为我们试图放入Router.configure。我不这样做,这里有一些关于我如何实现它的细节。

首先,我为router.js文件中的每个路径设置了一个控制器(我也有Router.configure()函数。看起来像这样:

Router.map(function () {
    this.route("login", {path: "/login", controller: "LoginController"});
    // other routes
}

接下来,我创建一个控制器,我存储在与客户端视图模板相同的文件夹中。它看起来像是:

this.LoginController = RouteController.extend({
    template: "Login",


    yieldTemplates: {
        /*YIELD_TEMPLATES*/
    },

    onBeforeAction: function() {
        /*BEFORE_FUNCTION*/
        this.next();
    },

    action: function() {
        if(this.isReady()) { this.render(); } else { this.render("loading"); }
        /*ACTION_FUNCTION*/
    },

    isReady: function() {


        var subs = [
        ];
        var ready = true;
        _.each(subs, function(sub) {
            if(!sub.ready())
                ready = false;
        });
        return ready;
    },

    data: function() {


        return {
            params: this.params || {}
        };
        /*DATA_FUNCTION*/
    },

    onAfterAction: function() {
    }
});

因此,当我使用控制器扩展路由时,此action函数正在工作。也许它会解决你的问题。

为了完整起见,我的Router.configure()看起来像是这样的:

Router.configure({
  templateNameConverter: "upperCamelCase",
  routeControllerNameConverter: "upperCamelCase",
  layoutTemplate: "layout",
  notFoundTemplate: "notFound",
  loadingTemplate: "loading",
 //I removed the rest because it is useless.
});