2016-10-14 14 views
0

ドキュメントから詳細な調査を行った後、カスタムウィジェットが必要なものを達成するための最良の方法です:タイトルで記事/ブログ投稿をロードするオートコンプリートドロップダウンユーザータイプ(npm jquery-autocomplete、https://www.npmjs.com/package/jquery-autocompleteを選択しましたが、この機能を実装するのは簡単だと思っていましたが、おそらくapos自体の中には簡単な方法があります)。サードパーティのnpm jqueryモジュールを使用したカスタムウィジェット

私はウィジェットのチュートリアルの指示に従いましたが、これはほとんど私がこのフックアップしていると思うが、検索ウィジェット(ビュー)がレンダリングされず、代わりに空の要素divクラス= "apos-area" data-apos-area = ""要素。これは、すべての部分をリンクする間に欠けている部分があることを示しますが、ドキュメントのサンプルコードに基づいて欠けている部分を特定することはできません。

質問1:search.htmlビューの読み込みを維持するために、以下のコードには何が欠けていますか?

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 \モジュール\検索ウィジェット\ビュー

app.js \ 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> 

Page

質問#2は、検索ウィジェットの\ 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> 

答えて

1

私がP'unk Avenueのアポストロフィーチームの頭です。

最初に、ウィジェットを提供するモジュールは、 "-widget"ではなく "-widgets"で終わる名前を持つ必要があります。それは複数でなければなりません(MAP - モジュールは複数です)。これは、ウィジェットのすべてのサーバー側のニーズを管理するモジュールの単一インスタンスが存在するためです(これは「シングルトンパターン」と呼ばれます)。これは「1つのウィジェット」ではなく、この種のウィジェットをすべて管理するモジュールです。

pageBeforeSendにコードを追加すると、今度はで実行されます。 - このページにウィジェットが含まれているかどうかは関係ありません。それは長いショットではパフォーマンスに最適ではありません。特に、サイト上のすべてのブログ記事を読み込んでいるためです。物事は速く減速します。

apostrophe-twitter-widgetsモジュールとそのソースコードを参照することを強くお勧めします。とりわけ、このモジュールは、ページ上に実際にウィジェットのインスタンスがあり、知りたいときにウィジェットにデータを供給するためのサーバー側のExpressルートを実装します。そして、ウィジェットはブラウザ側で呼び出され、ページ上にその種類のウィジェットがある場合に呼び出されるメソッド "ウィジェットプレーヤー"を実装します。

このモジュールにはカスタムブラウザサイドのアセットも含まれており、正しくアセットをプッシュします。このアセットは、この質問の表面のすぐ下に表示されるいくつかの質問にも答えます。

ただし、Apostropheはすでにjqueryオートコンプリートをブラウザにプッシュしています。それは、私たちが結合やタグに使うオートコンプリートの実装です。だから、あなたはその資産を押し込むことを心配する必要はありません。

サーバ側のルートは、Everything In The World All The Timeを取得するのではなく、autocompleteというカーソルフィルタを呼び出す必要があります。 (:アポストロフィは多くのオートコンプリートを使用しているので、プレフィックスと一致するものをフェッチして実装しても便利です。

カーソルフィルタが不明な人は、HOWTOを参照してくださいモデル層。

また、常に適切なモジュールのfindメソッドを使用し、それを改革し、戻すのに適切なブログ記事を作るものがあなた自身のために把握しようとしないでください。

であなたのルートが見えるかもしれませんlike:

// 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方式のエクスプレスルートがあります。ブラウザ側にプレーヤーメソッドを記述して、ジョブを終了します。あなたはそれらがどのように見えるか、どこにapostrophe-twitter-widgetsコードでそれらを置くかを見ることができます。もちろん、あなたのウィジェットのテンプレートのテキスト入力フィールドに.autocomplete()が呼び出されます。そして、jqueryオートコンプリートsourceオプションを/modules/search-widgets/autocompleteに設定します。

関連する問題