使用第三方 npm jquery 模块的自定义小部件
Custom widget using third party npm jquery module
在对文档进行更多研究后,自定义小部件似乎是尝试实现我需要的最佳方式:自动完成下拉列表可在用户键入时按标题加载 article/blog 个帖子 (我选择了 npm jquery-autocomplete、https://www.npmjs.com/package/jquery-autocomplete,因为我认为这个功能很容易实现,但也许 apos 本身有更简单的方法)。
我按照小部件教程中的说明进行操作,http://apostrophecms.org/docs/tutorials/getting-started/custom-widgets.html,我认为我几乎已经连接好了,但我没有看到呈现的搜索小部件(视图),而是 dom 显示一个空元素 div class="apos-area" data-apos-area="" 元素,这表明将所有部分链接在一起之间缺少一块,但我可以'根据文档示例代码找出缺失的部分。
这是问题 #1,下面的代码中缺少什么来阻止 search.html 视图加载?
app.js
modules: {
'search-widget': {}
}
lib\modules\search-widget\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\modules\search-widget\views\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\modules\apostrophe-pages\views\pages\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 object 吗?
<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>
如你所知,我是 P'unk Avenue 的 Apostrophe 团队的负责人。
首先,提供小部件的模块的名称应该以“-widgets”结尾,而不是“-widget”。它必须是复数(MAP - Modules Are Plural)。这是因为将有一个模块实例来管理小部件的所有服务器端需求(这被称为 "singleton pattern")。它不是 "one widget," 它是一个管理所有此类小部件的模块。
其次,像现在一样向 pageBeforeSend
添加代码将 运行 它始终 — 无论此页面是否包含小部件.从长远来看,这对于性能来说并不是最佳的。特别是因为您正在加载网站上的所有博客 post。事情会很快变慢。
我强烈建议您查看 apostrophe-twitter-widgets 模块及其源代码。除其他外,该模块实现了一个服务器端 Express 路由,专门为小部件提供数据,何时以及是否在页面上实际存在小部件实例并且它想知道。它实现了一个 "widget player," 方法,当页面上有这种小部件时,该方法会在浏览器端调用。
该模块还包含一些自定义浏览器端资产并正确推送它们,这也将回答我在这个问题的表面之下看到的一些问题。
但是,请注意,Apostrophe 已经总是将 jquery 自动完成推送到浏览器。这恰好是我们用于连接和标记的自动完成实现。因此,您无需担心推动该资产。
您的服务器端路由应该调用 autocomplete
游标过滤器,而不是一直获取世界上的一切。 (: Apostrophe 经常使用自动完成功能,因此它已经提供了一种方便的方式,可以以一种智能且实现良好的方式获取与前缀匹配的内容。
如果您不清楚游标过滤器,请务必阅读有关使用模型层的 HOWTO。
此外,始终使用适当模块的 find
方法,不要重新发明它并尝试自己弄清楚是什么让博客 post 适合 return。
您的路线可能如下所示:
// 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
函数。
现在 /modules/search-widgets/autocomplete
有一条 GET 方法 Express 路线等待您的来信。通过在浏览器端编写一个播放器方法来完成这项工作。您可以在 apostrophe-twitter-widgets
代码中看到它们的外观以及将它们放在何处。当然,您的窗口小部件模板中的文本输入字段会调用 .autocomplete()
。它将 jquery 自动完成 source
选项设置为 /modules/search-widgets/autocomplete
。
希望对您有所帮助!
在对文档进行更多研究后,自定义小部件似乎是尝试实现我需要的最佳方式:自动完成下拉列表可在用户键入时按标题加载 article/blog 个帖子 (我选择了 npm jquery-autocomplete、https://www.npmjs.com/package/jquery-autocomplete,因为我认为这个功能很容易实现,但也许 apos 本身有更简单的方法)。
我按照小部件教程中的说明进行操作,http://apostrophecms.org/docs/tutorials/getting-started/custom-widgets.html,我认为我几乎已经连接好了,但我没有看到呈现的搜索小部件(视图),而是 dom 显示一个空元素 div class="apos-area" data-apos-area="" 元素,这表明将所有部分链接在一起之间缺少一块,但我可以'根据文档示例代码找出缺失的部分。
这是问题 #1,下面的代码中缺少什么来阻止 search.html 视图加载?
app.js
modules: {
'search-widget': {}
}
lib\modules\search-widget\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\modules\search-widget\views\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\modules\apostrophe-pages\views\pages\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 object 吗?
<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>
如你所知,我是 P'unk Avenue 的 Apostrophe 团队的负责人。
首先,提供小部件的模块的名称应该以“-widgets”结尾,而不是“-widget”。它必须是复数(MAP - Modules Are Plural)。这是因为将有一个模块实例来管理小部件的所有服务器端需求(这被称为 "singleton pattern")。它不是 "one widget," 它是一个管理所有此类小部件的模块。
其次,像现在一样向 pageBeforeSend
添加代码将 运行 它始终 — 无论此页面是否包含小部件.从长远来看,这对于性能来说并不是最佳的。特别是因为您正在加载网站上的所有博客 post。事情会很快变慢。
我强烈建议您查看 apostrophe-twitter-widgets 模块及其源代码。除其他外,该模块实现了一个服务器端 Express 路由,专门为小部件提供数据,何时以及是否在页面上实际存在小部件实例并且它想知道。它实现了一个 "widget player," 方法,当页面上有这种小部件时,该方法会在浏览器端调用。
该模块还包含一些自定义浏览器端资产并正确推送它们,这也将回答我在这个问题的表面之下看到的一些问题。
但是,请注意,Apostrophe 已经总是将 jquery 自动完成推送到浏览器。这恰好是我们用于连接和标记的自动完成实现。因此,您无需担心推动该资产。
您的服务器端路由应该调用 autocomplete
游标过滤器,而不是一直获取世界上的一切。 (: Apostrophe 经常使用自动完成功能,因此它已经提供了一种方便的方式,可以以一种智能且实现良好的方式获取与前缀匹配的内容。
如果您不清楚游标过滤器,请务必阅读有关使用模型层的 HOWTO。
此外,始终使用适当模块的 find
方法,不要重新发明它并尝试自己弄清楚是什么让博客 post 适合 return。
您的路线可能如下所示:
// 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
函数。
现在 /modules/search-widgets/autocomplete
有一条 GET 方法 Express 路线等待您的来信。通过在浏览器端编写一个播放器方法来完成这项工作。您可以在 apostrophe-twitter-widgets
代码中看到它们的外观以及将它们放在何处。当然,您的窗口小部件模板中的文本输入字段会调用 .autocomplete()
。它将 jquery 自动完成 source
选项设置为 /modules/search-widgets/autocomplete
。
希望对您有所帮助!