javascript - keystone.js : how can I display content from 2 different models on my index page

标签 javascript jquery node.js handlebars.js keystonejs

我正在一个项目中使用 keystone.js。我正在使用 Handlebars(hbs) 进行模板化 我想要做什么:在我的索引页面上,我想显示一个 slider (用 unslider.js 解决了这个问题,所以我只需要能够显示 slider 模型中的图像和文本)和 3 个最新事件(有效)。 这是到目前为止我的代码:

这是我的事件模型

var keystone = require('keystone');
var Types = keystone.Field.Types;

/**
 * Event Model
 * ==========
 */

var Event = new keystone.List('Event', {
    map: { name: 'title' },
    autokey: { path: 'slug', from: 'title', unique: true },
});

Event.add({
    title: { type: String, required: true },
    state: { type: Types.Select, options: 'draft, published, archived', default: 'draft', index: true },
    author: { type: Types.Relationship, ref: 'User', index: true },
    publishedDate: { type: Types.Date, index: true, dependsOn: { state: 'published' } },
    image: { type: Types.CloudinaryImage },
    content: {
        brief: { type: Types.Html, wysiwyg: true, height: 150 },
        extended: { type: Types.Html, wysiwyg: true, height: 400 },
    },
    eventcategories: { type: Types.Relationship, ref: 'EventCategory', many: true },
});

Event.schema.virtual('content.full').get(function () {
    return this.content.extended || this.content.brief;
});

Event.defaultColumns = 'title, state|20%, author|20%, publishedDate|20%';
Event.register();

这是我的 slider 模型

var keystone = require('keystone');
var Types = keystone.Field.Types;

/**
 * slider Model
 * ==========
 */

var Slider = new keystone.List('Slider', {
    map: { name: 'title' },
    autokey: { path: 'slug', from: 'title', unique: true },
});

Slider.add({
    title: { type: String, required: true },
    image: { type: Types.CloudinaryImage },
});

Slider.register();

两种模型在后端都能正常工作,这应该只是 View 中的问题......所以这里是索引 View

var keystone = require('keystone');

exports = module.exports = function (req, res) {

    var view = new keystone.View(req, res);


    var locals = res.locals;

    // Init locals
    locals.section = 'eventblog';
    locals.filters = {
        eventcategory: req.params.category,
    };


    // Set locals
    locals.section = 'slider';
    locals.data = {
        titles: [],  //maybe this is a problem?
        images: [],  //maybe this is a problem?
        events: [],
        eventcategories: [],
    }


    // locals.section is used to set the currently selected
    // item in the header navigation.
    locals.section = 'home';

    view.on('init', function (next) {

        var q = keystone.list('Event').paginate({
            page: req.query.page || 1,
            perPage: 3,
            maxPages: 1,
            filters: {
                state: 'published',
            },
        })
            .sort('-publishedDate')
            .populate('author categories');

        if (locals.data.eventcategory) {
            q.where('categories').in([locals.data.eventcategory]);
        }


        q.exec(function (err, results) {
            locals.data.events = results;
            next(err);
        });

    });










    // Render the view
    view.render('index');
};

这是我的index.hbs

<div class="container">


    <div class="my-slider">
        <ul>

            {{#each slider}}
                <!-- doesn't loop even once-->

                                <li>
                                    <img src="{{cloudinaryUrl image width='300' height='300'}}" >
                                    <p>{{title}}</p>
                                </li>

            {{/each}}

        </ul>
    </div>
    <!-- the code below works correctly -->
    <div class="events row">

        {{# each data.events.results}}
            <div class="col-md-4 col-lg-4">
                <h3><a href="{{eventUrl slug}}">{{{title}}}</a></h3>
                <p class=" text-muted">{{{categoryList categories prefix="Posted in "}}}
                    {{#if author.name.first}}by {{author.name.first}}{{/if}}
                </p>
                {{#if image}}<img src="{{{cloudinaryUrl image  height=160 crop='fit' }}}" class="img center-block">{{/if}}
                <p>{{{content.brief}}}</p>
                {{#if content.extended}}<p class="read-more"><a href="{{eventUrl slug}}">Read more...</a></p>{{/if}}
            </div>
        {{/each}}
    </div>
</div>

我真的希望我的问题很清楚并且有人可以帮助我

最佳答案

route 的代码设置了locals.data.events,这就是您可以从 Handlebars 使用它的原因。但是,您没有设置 locals.slider,这就是 {{#each slider}} 循环不执行的原因。

在你的 route ,你还需要做类似的事情

keystone.list('Slider').model.find().exec(function (err, results) {
    locals.sliders = restuls;
    next(err);
}

它填充locals.slider,以便您可以在 hbs 模板中执行{{#each slider}}。然后你的代码的其余部分应该可以正常工作。

(免责声明,我没有实际测试过这个,但它应该可以工作。如果没有,请尝试找出发生了什么。keystone demo project 中有很多此类代码的示例)

关于javascript - keystone.js : how can I display content from 2 different models on my index page,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42386136/

相关文章:

javascript - D3 - 从外部文件读取更新数据后的转换

javascript - 在 javascript 中显示值的竖线

javascript - 如何获得没有图像的链接?

php - 从 PHP 调用 Jquery AJAX 后强制重定向

javascript - Babel 创建输出目录但不转译任何文件

javascript - 如何在node js中发出多个请求

javascript - 如何在每 3 位数字后添加一个逗号?

javascript - 在哪里使用 preventDefault();在 jquery 中停止提交表单数据

javascript - 在map.arc()中循环Json对象

node.js - 在 $project 阶段 reshape 文档