为什么我在尝试使用Meteor搜索源包时遇到错误?

BoJ*_*man 6 javascript meteor

我在流星搜索源上遵循了这个教程并修改了示例,以便它符合我当前的需求.这是我的,它位于我的lib目录中collections.js

Guides = new Mongo.Collection("guides");
Run Code Online (Sandbox Code Playgroud)

我的客户端控制器中有以下代码.

var options = {
    keepHistory: 1000 * 60 * 5,
    localSearch: true
};

var fields = ['title'];

GuideSearch = new SearchSource('guides', fields, options);

Template.guide_list.helpers({
    getGuides: function () {
        return GuideSearch.getData({
            transform: function (matchText, regExp) {
                return matchText.replace(regExp, "<b>$&</b>")
            }
        });
    },

    isLoading: function () {
        return GuideSearch.getStatus().loading;
    }
});


Template.guide_list.events({
    "keyup #title": _.throttle(function(e) {
        var text = $(e.target).val().trim();
        GuideSearch.search(text);
    }, 200)
});
Run Code Online (Sandbox Code Playgroud)

这是我的服务器端代码

SearchSource.defineSource('guides', function(searchText, options) {
  if(searchText) {
    var regExp = buildRegExp(searchText);
    var selector = {title: regExp}
    return Guides.find(selector, options).fetch();
  } else {
    return Guides.find({}, options).fetch();
  }
});

function buildRegExp(searchText) {
  // this is a dumb implementation
  var parts = searchText.trim().split(/[ \-\:]+/);
  return new RegExp("(" + parts.join('|') + ")", "ig");
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我在输入字段中键入内容时收到以下错误消息

Exception in delivering result of invoking 'search.source': Meteor.makeErrorType/errorClass@http://10.0.3.162:3000/packages/meteor.js?9730f4ff059088b3f7f14c0672d155218a1802d4:525:15
._livedata_result@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:4625:23
Connection/onMessage@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:3365:7
._launchConnection/self.socket.onmessage/<@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:2734:11
_.forEach@http://10.0.3.162:3000/packages/underscore.js?46eaedbdeb6e71c82af1b16f51c7da4127d6f285:149:7
._launchConnection/self.socket.onmessage@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:2733:9
REventTarget.prototype.dispatchEvent@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:173:9
SockJS.prototype._dispatchMessage@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1158:5
SockJS.prototype._didMessage@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1216:13
SockJS.websocket/that.ws.onmessage@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1363:9
Run Code Online (Sandbox Code Playgroud)

这是我的模板代码:

template(name="guide_list")
    .format-properly
        .container-fluid
            .input-group#adv-search
                .form-horizontal(role="form" method="POST" action="#")
                    .col-md-6
                        .form-group
                            label(for="contain") Guide title
                            input.form-control(type="text" id="title")
                    .col-md-6
                        .form-group
                            label(for="contain") Author
                            input.form-control(type="text" name="author")
                    .col-md-6
                        .form-group
                            label(for="hero") Select a hero
                            select.form-control(name="hero")
                                option(value="all" selected) All Heroes
                                option(value="Druid") Druid
                                option(value="Hunter") Hunter
                                option(value="Mage") Mage
                                option(value="Paladin") Paladin
                                option(value="Priest") Priest
                                option(value="Rogue") Rogue
                                option(value="Shaman") Shaman
                                option(value="Warlock") Warlock
                                option(value="Warrior") Warrior
                    .col-md-6
                        .form-group
                            label(for="filter") Filter by
                            select.form-control(name="filterBy")
                               option(value="0" selected) All guides
                               option(value="most_viewed") Most viewed
                               option(value="top_rated") Top rated
                               option(value="most_commented") Most commented

        .container-fluid
            .table-responsive
                table.table.table-hover
                    thead
                        tr
                            th hero
                            th title
                            th author
                            th updated
                            th dust
                            th
                                span.glyphicon.glyphicon-eye-open
                            th
                                span.glyphicon.glyphicon-heart
                            th
                                span.glyphicon.glyphicon-comment
                    tbody
                        each guides
                            tr
                                td {{hero}}
                                td
                                    a(href="/guide/{{formatId _id}}") {{title}}
                                td {{authorUsername}}
                                td {{moFormat modifiedAt 'YYYY-MM-DD'}}
                                td {{dust}}
                                td {{hitCount}}
                                td {{rating}}
                                td {{commentCount}}

                    tbody
                        each getGuides
                            tr
                                td {{hero}}
                                td
                                    a(href="/guide/{{formatId _id}}") {{title}}
                                td {{authorUsername}}
                                td {{moFormat modifiedAt 'YYYY-MM-DD'}}
                                td {{dust}}
                                td {{hitCount}}
                                td {{rating}}
                                td {{commentCount}}
Run Code Online (Sandbox Code Playgroud)

任何帮助或建议都非常感谢!

编辑:我将search-source软件包更新到1.4.2

Mas*_*rAM 3

我认为问题在于缺少options传递给GuideSearch.search方法。

这导致搜索定义处理程序获取null选项。

SearchSource.defineSource('guides', function(searchText, options) {
  if(searchText) {
    var regExp = buildRegExp(searchText);
    var selector = {title: regExp}
    return Guides.find(selector, options).fetch(); //illegal
  } else {
    return Guides.find({}, options).fetch();
  }
});
Run Code Online (Sandbox Code Playgroud)

这会导致集合的find()方法获得空options参数,如果提供该参数,则该参数必须是一个对象(而不是null)。

options因此,要么检查数据源中是否为 null并向该find()方法传递一个空对象(或什么都不传递),要么向该GuideSearch.search()方法传递一个空对象:

Template.guide_list.events({
    "keyup #title": _.throttle(function(e) {
        var text = $(e.target).val().trim();
        GuideSearch.search(text, {}); // here
    }, 200)
});
Run Code Online (Sandbox Code Playgroud)

无论如何,您应该确保它们options不在null服务器方法中,如 @webdeb 的答案所示。

此外,目前某些包(checkejson)必须作为依赖项添加到您的应用程序中,因为meteorhacks:search-source包在不声明依赖项的情况下使用它们。这是由于 v1.2.0 中引入的更改所致。(在此之前,这些符号自动可用于包)。

为了获得最初可用的所有结果,您可以在首次创建模板时触发搜索。请注意,当您拥有大量数据时,这可能会相当昂贵,因此您可能应该限制从服务器上的搜索定义处理程序返回的结果。

Template.guide_list.onCreated(function () {
  GuideSearch.search('', {});
});
Run Code Online (Sandbox Code Playgroud)

为了在搜索结果中正确显示标题,您可以使用Spacebars.SafeString()blaze 知道将其呈现为 HTML。

Template.guide_list.helpers({
    getGuides: function () {
        return GuideSearch.getData({
            transform: function (matchText, regExp) {
              return Spacebars.SafeString(matchText.replace(regExp, "<b>$&</b>"))
            }
        });
    },
    formatId: function(id) {
      return id;
    },
    moFormat: function(date, format) {
        return moment(date).format(format);
    },
    isLoading: function () {
        return GuideSearch.getStatus().loading;
    }
});

Template.guide_list.events({
    "keyup #title": _.throttle(function(e) {
        var text = $(e.target).val().trim();
        GuideSearch.search(text, {/* your options here */});
    }, 200)
});
Run Code Online (Sandbox Code Playgroud)

或者,也可以使用三大括号表示法:

SearchSource.defineSource('guides', function(searchText, options) {
  if(searchText) {
    var regExp = buildRegExp(searchText);
    var selector = {title: regExp}
    return Guides.find(selector, options).fetch(); //illegal
  } else {
    return Guides.find({}, options).fetch();
  }
});
Run Code Online (Sandbox Code Playgroud)

警告:执行此操作时请务必对其进行消毒matchText

出版物应该与结果无关,因为该包使用自己的集合。