从文档中做了更多研究后,看起来自定义小部件是尝试实现我需要的最佳方式:自动完成下拉按用户类型按标题加载文章/博客帖子(我选择了npm jquery -autocomplete,https://www.npmjs.com/package/jquery-autocomplete,因为我认为这个功能很容易实现,但也许在本身内有一种更简单的方法)。
我按照小部件教程http://apostrophecms.org/docs/tutorials/getting-started/custom-widgets.html中的说明进行操作,并且认为我几乎已经将其连接起来,但我没有看到呈现的搜索小部件(视图),而是dom显示了空元素div class =" apos-area"数据者-面积=""元素,表示在将所有部分链接在一起之间缺少一块,但我无法根据文档示例代码识别缺失的部分。
这是问题#1,下面的代码中缺少什么来阻止search.html视图加载?
app.js
modules: {
'search-widget': {}
}
的lib \模块\搜索插件\ index.js
module.exports = {
extend: 'apostrophe-widgets',
label: 'SiteSearch',
addFields: [{
type: 'string',
name: 'title',
label: 'Title'
},
{
type: 'string',
name: 'url',
label: 'Url'
}
],
construct: function(self, options) {
//load third party styles and scripts?
var superPushAssets = self.pushAssets;
self.pushAssets = function() {
superPushAssets();
self.pushAsset('stylesheet', 'autocomplete', { when: 'always' });
self.pushAsset('script', 'autocomplete', { when: 'always' })
};
//get the data
self.pageBeforeSend = function(req, callback) {
var criteria = [
{ "type": "apostrophe-blog" },
{ "published": true }
];
criteria = { $and: criteria };
self.apos.docs.find(req, criteria).sort({ title: 1 }).toArray(function(err, autocomplete) {
if (err) {
return callback(err);
}
//Can I do something like this to load the widget data?
req.data.autocomplete = autocomplete;
return callback(null);
});
}
}
};
的lib \模块\搜索窗口小部件\视图\ search.html
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class="form-control input-lg" id="site-search" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-info btn-lg" type="button">
<i class="glyphicon glyphicon-search"></i>
</button>
</span>
</div>
</div>
的lib \模块\撇号的页面\视图\页面\ home.html的
{% extends 'apostrophe-templates:layout.html' %} {% block bodyClass %}{{ super() }} home-page{% endblock %} {% block title %}Help Site: {{ data.page.title | e }}{% endblock %} {% block main %}
<section id="promo" class="promo section offset-header">
<div class="container text-center">
<div class="row">
<div class="col-md-offset-2 col-md-8 col-sm-6 col-xs-12">
<!--search widget-->
{{ apos.singleton(data.page, 'search', 'search-widget') }}
</div>
</div>
</div>
</section>
问题#2是,在search-widget \ index.js构造函数中,这是加载将其呈现给dom并使用它所需的第三方资产的正确方法吗?
问题#3是,在search.html中,我可以简单地使用data.page将数据发送到jquery-autocomplete对象吗?
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class="form-control input-lg" id="site-search" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-info btn-lg" type="button">
<i class="glyphicon glyphicon-search"></i>
</button>
</span>
</div>
</div>
<script>
$(function() {
$("#site-search").autocomplete({
source: {{ data.autocomplete | json }}
});
});
</script>
答案 0 :(得分:1)
如你所知,我是P'unk Avenue的Apostrophe团队的负责人。
首先,提供小部件的模块的名称应以“-widgets”结尾,而不是“-widget”。它必须是复数(MAP - 模块是多个)。这是因为将有一个模块的单个实例来管理小部件的所有服务器端需求(这被称为“单例模式”)。它不是“一个小部件”,它是一个管理这种小部件的模块。
其次,现在将代码添加到pageBeforeSend
将始终在运行 - 无论此页面是否包含小部件。这远远不是最佳表现。特别是因为您正在加载网站上的所有博客帖子。事情会慢下来。
我强烈建议您查看apostrophe-twitter-widgets模块及其源代码。除此之外,该模块实现了一个服务器端Express路由,专门用于向窗口小部件提供数据,当窗口上实际存在窗口小部件的实例并且它想要知道时。它实现了一个“小部件播放器”,一种在浏览器端调用的方法,如果页面上有这种小部件的话。
该模块还包含一些自定义浏览器端资产并正确推送它们,这也可以回答我在这个问题的表面下可以看到的一些问题。
但是,请注意,正好相反,Apostrophe已经将jquery自动完成功能推送到浏览器。这恰好是我们用于连接和标记的自动完成实现。因此,您无需担心推送该资产。
你的服务器端路由应该调用autocomplete
游标过滤器而不是一直在全世界取得一切。 (:Apostrophe使用自动完成功能很多,所以它已经提供了一种便利,可以通过智能且实现良好的方式获取与前缀匹配的内容。
如果您对光标过滤器不清楚,请务必阅读使用模型图层的HOWTO。
此外,始终使用相应模块的find
方法,不要重新发明它,并尝试自己弄清楚什么使博客文章适合返回。
您的路线可能如下:
// Inside the construct function of your module...
self.route('get', 'autocomplete', function(req, res) {
return self.apos.docs.getManager('apostrophe-blog')
.find()
.autocomplete(req.query.term)
.limit(10)
.projection({
areas: false,
joins: false
})
.toArray(function(err, posts) {
if (err) {
res.statusCode = 500;
return res.send('error');
}
return res.send(_.map(posts, function(post) {
return {
value: post._url,
label: post.title
}
}));
}
);
});
这将进入模块的construct
功能。
现在有一条GET-Express Express路线等着您/modules/search-widgets/autocomplete
收听。通过在浏览器端编写播放器方法来完成作业。您可以看到它们的外观以及将它们放在apostrophe-twitter-widgets
代码中的位置。当然,您的小部件将在小部件模板中的文本输入字段上调用.autocomplete()
。它会将jquery自动填充source
选项设置为/modules/search-widgets/autocomplete
。
希望这有用!