0

在对文档进行了更多研究之后,看起来自定义小部件是尝试实现我所需要的最佳方式:一个自动完成下拉菜单,在用户类型时按标题加载文章/博客文章(我选择了 npm jquery-autocomplete,https://www.npmjs.com/package/jquery-autocomplete,因为我认为这个功能很容易实现,但也许 pos 本身有更简单的方法)。

我按照关于小部件的教程http://apostrophecms.org/docs/tutorials/getting-started/custom-widgets.html中的说明进行操作,并认为我几乎已经将其连接起来,但我没有看到搜索小部件(视图)呈现,而不是 dom 显示一个空元素 div class="apos-area" data-apos-area="" 元素,这表明在将所有部分链接在一起之间缺少一块,但我不能根据文档示例代码识别缺失的部分。

这是问题 #1,下面的代码中缺少什么来阻止 search.html 视图加载?

应用程序.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\撇号-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 对象吗?

<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>
4

1 回答 1

1

如你所知,我是朋克大道 Apostrophe 团队的负责人。

首先,提供小部件的模块的名称应该以“-widgets”结尾,而不是“-widget”。它必须是复数(MAP - Modules Are Plural)。这是因为将有一个模块实例来管理小部件的所有服务器端需求(这被称为“单例模式”)。它不是“一个小部件”,而是一个管理所有此类小部件的模块。

其次,pageBeforeSend按照现在的方式添加代码将始终运行它——无论此页面是否包含小部件。从长远来看,这对于性能来说并不是最佳的。特别是因为您正在加载网站上的所有博客文章。事情会很快放缓。

我强烈建议您查看apostrophe-twitter-widgets模块及其源代码。除其他外,该模块实现了一个服务器端 Express 路由,专门用于向小部件提供数据,何时以及是否在页面上实际存在小部件实例并且它想知道。它还实现了一个“小部件播放器”,当页面上有此类小部件时,该方法会在浏览器端调用。

该模块还包含一些自定义浏览器端资产并正确推送它们,这也将回答我在这个问题表面下看到的一些问题。

但是,请注意,当它发生时,撇号已经总是将 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-method Express 路线等待您的来信/modules/search-widgets/autocomplete。通过在浏览器端编写一个播放器方法来完成这项工作。您可以看到它们的外观以及将它们放在apostrophe-twitter-widgets代码中的什么位置。当然,您的将调用.autocomplete()小部件模板中的文本输入字段。它会将 jquery 自动完成source选项设置为/modules/search-widgets/autocomplete.

希望这有帮助!

于 2016-10-15T22:15:49.060 回答