【问题标题】:Meteor - autocomplete with "distinct" feature?Meteor - 具有“独特”功能的自动完成功能?
【发布时间】:2015-05-04 20:52:43
【问题描述】:

我有一个歌曲集,其中包含以下格式的数据:

{artist:"Dream Theater", title: "Pull me under"}, {artist:"Dream Theater", title: "Finally free"}

我正在使用包 mizzao-autocomplete 有超过 5000 个条目,所以我肯定需要服务器端自动完成。 在服务器上我发布了集合:

Meteor.publish("autocompleteArtists", function(selector, options) {
  Autocomplete.publishCursor(Songs.find(selector, options), this);
  this.ready();
});

客户端订阅如下:

Template.home.helpers({
    settings: function() {
        return {
            position: "top",
            limit: 5,
            rules: [{
                collection: 'Songs',
                subscription: 'autocompleteArtists',
                field: "artist",
                template: Template.songItem
            }]
        };
    }
});

我应该在 settings() 函数中同时拥有收藏和订阅吗?

最后一部分,客户端模板:

{{> inputAutocomplete settings=settings id="artistInput" type="text" placeholder="Artist" length="20"}}

我的目的是寻找一个艺术家,当我选择它时,订阅一个简单的服务器发布,它返回属于该艺术家的所有歌曲。问题是,如果我有同一个艺术家的多个条目,当然,结果列表会多次显示该艺术家。我需要以某种方式发布一个“独特”的发布,它会返回所有艺术家,但 Meteor 中没有这样的功能。我发现了一些实现聚合和不同的东西,但我看不到如何使用 Autocomplete publishCursor 功能......我的临时解决方案是非规范化并添加 Artists 集合,但我不应该这样做。

有没有更简单的方法?

【问题讨论】:

    标签: meteor


    【解决方案1】:

    如果您想在服务器上进行自动完成,您似乎需要 subscriptioncollection 参数。

    不幸的是,正如您所注意到的,实际上并没有一种很好的方法来强制执行唯一性。您可以使用聚合,但除非它返回一个光标,否则它看起来不是您想要的(例如,Meteorhacks:aggregate 不是)。

    解决此问题的一种(简单?)方法是识别每个艺术家的单个实例并标记它(autocomplete: true);那么您可以使用filter 选项来过滤自动完成= true 的位置。如果人们手动输入歌曲,这真的很容易:

    Meteor.methods({
      insertSong: function(song, artist) { 
        var entry = {title: song, artist: artist, autocomplete: false};
        if (Songs.find({artist: artist}).count() === 0) { entry.autocomplete = true; }
        Songs.insert(entry);
      }
    });
    

    然后你的rules 只需要包含一个filter 对象:

    ...
    rules: [{
                collection: 'Songs',
                subscription: 'autocompleteArtists',
                field: "artist",
                template: Template.songItem,
                filter: {autocomplete: true}
            }]
    ...
    

    然后,您将需要另一个 pub/sub 来实际显示相关艺术家的歌曲:

    // Server
    Meteor.publish("songsByArtist", function(artist) { 
      return Songs.find({artist: artist});
    });
    
    // Client
    Template.home.events({ // listen for selection and subscribe
      "autocompleteselect input": function(event, template, doc) {
    
       Meteor.subscribe("songsByArtist", doc.artist);
      }
    });
    
    // And you can iterate like so with a helper:
    songsToDisplay: function() { 
      return Songs.find();
    }
    
    <!-- HTML -->
    {{#each songsToDisplay}}
      {{> songAndArtist}}
    {{/each}}
    

    您可以在MeteorPad. 上玩弄它,抱歉,我想不出更好的方法。

    【讨论】:

    • 这是一个相当聪明的把戏:) 我会试试的,正如你所说,这在插入数据时可以很容易地完成(对于现有数据也可以处理一次,但事实并非如此)。我还想在服务器中使用本机 MongoDB 客户端进行聚合,不确定这是否会返回一个游标..
    猜你喜欢
    • 2017-04-24
    • 2022-08-15
    • 2017-01-23
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    相关资源
    最近更新 更多