【问题标题】:Meteor Template Not Rendering Content Inside HTML ElementsMeteor 模板未在 HTML 元素中呈现内容
【发布时间】:2015-10-27 21:05:56
【问题描述】:

我想要做什么

看起来很简单,但我正在尝试使用 Meteor 的帐户系统和 Iron:Router 来为 Web 应用程序设置管理系统。管理部分是应用程序中唯一具有帐户的部分。管理部分位于/admin,并有一个登录模板,以及一个应在管理员登录后显示的数据模板。

代码

基础路由器

Router.route('/', {
    template: 'user' // Not shown; works fine
});
Router.route('/admin', {
    template: 'adminDataPage'
});

模板

<template name="adminLoginPage">
    <div class="cover-wrapper-outer page-admin login">
        <div class="cover-wrapper-inner">
            <div class="cover-container">
                <div class="cover">
                    <form class="admin-login-form">
                        <div class="alert alert-danger login-failure">
                            The username or password is incorrect.
                        </div>
                        <input class="form-control username" name="username" type="text" placeholder="Username">
                        <input class="form-control password" name="password" type="password" placeholder="Password">
                        <input class="form-control submit" name="submit" type="submit" value="Log in">
                    </form>
                </div>
            </div>
        </div>
    </div>
</template>
<template name="adminDataPage">
    <div class="container-fluid page-admin admin-content">
        <div class="row">
            <div class="col-xs-12">
                <div class="scrolling-table">
                    <table class="table table-striped">
                        <thead>
                            <tr>
                                <th>Year</th>
                                <th>Make</th>
                                <th>Model</th>
                                <th>Engine</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                            <td>Year</td>
                            <td>Make</td>
                            <td>Model</td>
                            <td>Engine</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</template>
<template name="adminLoggingIn">
    Logging in...
</template>

(目前这还不完整,但与问题无关。)

问题

无论我做什么,adminDataPage 模板中的内容都不会被渲染。然而,任何 不是 在 HTML 元素 中的东西都会被呈现。例如,这个渲染:

<template name="adminDataPage">
    Hello world!
</template>

以下中的world 不会呈现:

<template name="adminDataPage">
    Hello <span>world</span>!
</template>

adminLoggingIn 模板也是如此。但是,adminLoginPage 模板中的任何内容都可以正常工作。

本质上,显示登录框,客户端Javascript(未显示)负责登录用户,用户看到Logging in...,然后用户什么也看不到,浏览器的检查器中也没有显示(除非adminDataPage 模板中有未嵌套的纯文本)。

我尝试过的

如果当前用户

<template name="adminDataPage">
    {{#if currentUser}}
        <div class="container-fluid page-admin admin-content">
            <div class="row">
                <div class="col-xs-12">
                    <div class="scrolling-table">
                        <table class="table table-striped">
                            <thead>
                                <tr>
                                    <th>Year</th>
                                    <th>Make</th>
                                    <th>Model</th>
                                    <th>Engine</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                <td>Year</td>
                                <td>Make</td>
                                <td>Model</td>
                                <td>Engine</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    {{else}}
        <div class="cover-wrapper-outer page-admin login">
            <div class="cover-wrapper-inner">
                <div class="cover-container">
                    <div class="cover">
                        <form class="admin-login-form">
                            <div class="alert alert-danger login-failure">
                                The username or password is incorrect.
                            </div>
                            <input class="form-control username" name="username" type="text" placeholder="Username">
                            <input class="form-control password" name="password" type="password" placeholder="Password">
                            <input class="form-control submit" name="submit" type="submit" value="Log in">
                        </form>
                    </div>
                </div>
            </div>
        </div>
    {{/if}}
</template>

这将按预期在未登录时呈现登录页面。但是,一旦登录,什么都不会呈现。我也尝试过整合{{#if loggingIn}},但无济于事。

铁:路由器挂钩

Router.route('/', {
    template: 'user'
});
Router.route('/admin', {
    template: 'adminDataPage'
});
var requireLogin = function() {
    if (! Meteor.user()) {
        if (Meteor.loggingIn()) {
            this.render('adminLoggingIn');
        } else {
            this.render('adminLoginPage');
        }
    } else {
        this.next();
    }
};
Router.onBeforeAction(requireLogin, {only: 'admin'});

如果未登录,这将按预期呈现登录页面,但不会呈现adminLoggingInadminLoginPage 模板内的HTML 元素内的任何内容。

规格

流星 v1.1.0.3

Iron:Router v1.0.9

结论

我非常困惑为什么 Meteor(或 Iron:Router)拒绝在某些上下文中呈现某些内容。当然,如果有人有任何想法可以帮助解决这个问题,请拍下;不胜感激。

【问题讨论】:

  • 不认为这会解决问题,但我会明确地将name: 'admin' 指定给“/admin”路由,以确保onBeforeAction 正确应用于“管理员”路线。尽管the iron router documentation 声明“路由器将根据路径猜测其名称”,但并未明确说明如何它将猜测它。
  • 好点,这将防止一些未来的歧义。但正如你所怀疑的那样,这并没有解决我的问题。谢谢!
  • 我也在流星论坛上看到过issues using Meteor.user()这种情况,用户对象还不能正确设置,所以通常最好使用Meteor.userId()。跨度>
  • 我也尝试过,同时设置一个辅助变量并使用模板{{#if user_logged_in}}。我什至尝试在钩子中废弃Meteor.user() 并将其更改为简单的if (true),但问题仍然存在。不过再次感谢!

标签: meteor iron-router meteor-blaze meteor-accounts


【解决方案1】:

Blaze.render() 似乎在这里有问题。在控制台中使用 Blaze.render(Template.adminDataPage, document.body) 不会渲染任何东西,但就像我的问题一样,纯文本直接嵌套在 body 元素中。它不会在 body 下嵌套任何 DOM 元素。

为了进行测试,我创建了一个 DOM 元素 &lt;div class="test"&gt;&lt;/div&gt;,将其嵌套在页面主体中,并调用了 Blaze.render(Template.adminDataPage, $('.test')[0]),它可以正常工作。它的格式不正确,但它有效。

为 Iron:Router 添加一个布局模板以解决该问题,如下所示:

<template name="adminPage">
    <div class="test">
        {{> yield}}
    </div>
</template>
Router.route('/admin', {
    name: 'admin',
    template: 'adminDataPage',
    layoutTemplate: 'adminPage'
});
var requireLogin = function() {
    login_dep.depend();
    if (! Meteor.user()) {
        if (Meteor.loggingIn()) {
            this.render('adminLoggingIn');
            console.log('Logging in page');
        } else {
            this.render('adminLoginPage');
            console.log('Login page');
        }
    } else {
        this.next();
        console.log('Data page');
    }
};
Router.onBeforeAction(requireLogin, {only: 'admin'});

另外,将{{#if currentUser}} 嵌套在另一个元素中也可以:

<template name="adminPage">
    <div class="test">
        {{#if currentUser}}
            <div class="container-fluid page-admin admin-content">
                <div class="row">
                    <div class="col-xs-12">
                        <div class="scrolling-table">
                            <table class="table table-striped">
                                <thead>
                                    <tr>
                                        <th>Year</th>
                                        <th>Make</th>
                                        <th>Model</th>
                                        <th>Engine</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                    <td>Year</td>
                                    <td>Make</td>
                                    <td>Model</td>
                                    <td>Engine</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        {{else}}
            <div class="cover-wrapper-outer page-admin login">
                <div class="cover-wrapper-inner">
                    <div class="cover-container">
                        <div class="cover">
                            <form class="admin-login-form">
                                <div class="alert alert-danger login-failure">
                                    The username or password is incorrect.
                                </div>
                                <input class="form-control username" name="username" type="text" placeholder="Username">
                                <input class="form-control password" name="password" type="password" placeholder="Password">
                                <input class="form-control submit" name="submit" type="submit" value="Log in">
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        {{/if}}
    </div>
</template>
Router.route('/admin', {
    name: 'admin',
    template: 'adminPage'
});

我不确定为什么 Blaze 拒绝将某些元素附加到 body 元素,但这些是一些解决方法。

编辑

我发现一个更好的解决方法是添加一个 Blaze 可以预先添加模板 DOM 的元素。 Blaze.render(Template.adminDataPage, document.body, $('.render-fix')[0]) 在初始渲染时将具有 render-fix 类的隐藏元素放置在 DOM 中将起作用。本质上:

<template name="adminPage">
    {{#if currentUser}}
        <div>User logged in stuff</div>
    {{else}}
        <div>User not logged in stuff</div>
    {{/if}}
    <div class="render-fix" style="display: none"></div>
</template>

在我看来,Blaze 在初始渲染后不会将任何模板附加到正文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    相关资源
    最近更新 更多