Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

シングルページアプリを...turbolinksのために捨てますか?

Turbolinks-おそらくRailsの世界で最も軽蔑されている言葉の1つです。

たぶん、あなたはそれを試してみました。新しいプロジェクトまたは既存のアプリにターボリンクを含めました。そしてすぐに、アプリは奇妙で素晴らしい方法で失敗し始めました。修正は同じくらい簡単でした。ターボリンクをオフにしてください。

...しかし、一部の企業はそれを機能させています。ここHoneybadgerでは、それを機能させました-そして私たちは天才ではありません。

答えはとても単純なので、私はそれを持ち出すのをほとんどためらっています。しかし、RubyNationとMadison+ Rubyでこのテーマについて話し合った後、人々はこのトピックが役に立ったと感じているようです。では、掘り下げてみましょう。

ターボリンクとPJAXの仕組み

シングルページアプリを...turbolinksのために捨てますか?

TurbolinksとPJAXは基本的に同じように機能します。それらはとても似ているので、これからはPJAXとだけ言います。 :)

PJAXは、2ページのリクエストで理解できます。ユーザーが初めてページをリクエストすると、他の「従来の」Railsページと同じように配信されます。しかし、ユーザーがPJAX対応のリンクをクリックすると、何か特別なことが起こります。ページを完全にリロードする代わりに、ページの一部のみが更新されます。これはAJAXを介して行われます。

これにより、いくつかの問題を回避しながら、シングルページアプリの多くの利点が得られます。

  • PJAXアプリは、リクエストごとにページを完全にリロードする必要がなくなるため、シングルページアプリと同じようにスッキリしているように見えることがよくあります。
  • フロントエンドとバックエンドの開発に同じスタックを使用できます
  • ユーザーがJSを無効にすると、PJAXアプリはデフォルトで正常に機能しなくなります
  • PJAXアプリは、より簡単にアクセス可能になり、SEOに対応します
ターボリンクの実装

あなたのためにPJAXの重労働を行うライブラリはたくさんあります。 Turbolinksはおそらく最もよく知られています。設定は、Gemfileにturbolinksgemを含めるだけです。

gem 'turbolinks' 

...そしてJSをapp/asset / javascripts / application.js

に含めます
//= require turbolinks

これで、アプリをリロードすると、すべての内部リンクがターボリンクになります。それらをクリックすると、新しいページがAJAX経由で要求され、現在のドキュメントに挿入されます。

jquery-pjaxの実装

ここHoneybadgerでは、元々Githubによって開発されたPJAXライブラリを使用しています。 Turbolinksよりも少し多くの構成が必要ですが、かなり柔軟性があります。

すべてのリンクがPJAXであると想定する代わりに、それを制御できます。また、ページ上のPJAXコンテンツを挿入する場所を制御することもできます。

最初に行う必要があるのは、HTMLにコンテナを追加することです

<div class="container" id="pjax-container">
  Go to <a href="/page/2">next page</a>.
</div>

次に、PJAXリンクを設定する必要があります:

$(document).pjax('a', '#pjax-container')

最後に、PJAXリクエストでレイアウトをレンダリングしないようにrailsに指示します。このようなことをしなければ、ヘッダーとフッターが重複してしまいます。すなわち。あなたのウェブサイトはインセプションのようになります。

def index
  if request.headers['X-PJAX']
    render :layout => false
  end
end

それはそれほど簡単ではありません!

わかりました、それは私が許可したよりも少し複雑です。主に、ほとんどの人が話さない1つの大きな落とし穴が原因です。

ページが読み込まれるたびにDOMがクリアされない場合は、従来のRailsアプリで機能していた可能性のあるJSが非常に奇妙な方法で機能しなくなったことを意味します。

この理由は、私たちの多くが偶発的な名前の競合を助長する方法でJSを書くことを学んだからです。最も陰湿な犯人の1つは、単純なjqueryセレクターです。

// I may look innocent, but I'm not!
$(".something")
リロードしないページのJSを書き込む

リロードしないページのJSを作成する場合、競合が最大の問題になります。 JSがHTMLを操作するときに、最も奇妙でデバッグが難しい問題のいくつかが発生します。たとえば、通常のjQueryイベントハンドラーを見てみましょう。

$(document).on("click", ".hide-form", function() {
  $(".the-form").hide();
});

1ページでのみ実行される場合、これは完全に合理的です。しかし、DOMがリロードされない場合は、誰かがやって来て.hide-formのクラスを持つ別の要素を追加するのは時間の問題です。今、あなたは対立しています。

このような競合は、グローバル参照が多数ある場合に発生します。そして、どのようにしてグローバル参照の数を減らしますか?名前空間を使用します。

名前空間セレクター

以下のRubyクラスでは、1つのグローバル名(クラス名)を使用して、多くのメソッド名を非表示にしています。

# One global name hides two method names
class MyClass
  def method1
  end

  def method2
  end
end

名前空間DOM要素の組み込みサポートはありませんが(少なくともES6 WebComponentsが到着するまでは)、コーディング規則を使用して名前空間をシミュレートすることは可能です。

たとえば、タグ編集ウィジェットを実装したいとします。名前空間がないと、次のようになります。 3つのグローバル参照があることに注意してください。

// <input class="tags" type="text" />
// <button class="tag-submit">Save</button>
// <span class="tag-status"></span>

$(".tag-submit").click(function(){
  save($(".tags").val());
  $(".tag-status").html("Tags were saved");
});

ただし、「名前空間」を作成し、それに関連するすべての要素ルックアップを作成することで、グローバル参照の数を1つに減らすことができます。また、いくつかのクラスを完全に削除しました。

// <div class="tags-component">
//   <input type="text" />
//   <button>Save</button>
//   <span></span>
// </div>

$container = $("#tags-component")
$container.on("click", "button" function(){
  save($container.find("input").val());
  $container.find("span").html("Tags were saved");
});

簡単だと言いました。

上記の例では、DOM要素を「tags-component」のクラスを持つコンテナ内に配置することで名前空間を設定しました。その特定の名前について特別なことは何もありません。しかし、すべての名前空間コンテナに「-component」で終わるクラスがある命名規則を採用すると、非常に興味深いことが起こります。

間違ったグローバルセレクターを一目で認識できます。

許可するグローバルセレクターがコンポーネントのみであり、すべてのコンポーネントに「-component」で終わるクラスがある場合、不良なグローバルセレクターがあるかどうかが一目でわかります。

// Bad
$(".foo").blah()

// Ok
$(".foo-component".blah()

HTMLを制御するJSを簡単に見つけることができます

インタラクティブタグフォームをもう一度見てみましょう。フォームのHTMLを作成しました。次に、JSとCSSを追加する必要があります。しかし、それらのファイルはどこに置きますか?幸いなことに、名前空間の命名スキームがある場合、それはJSおよびCSSファイルの命名スキームに簡単に変換されます。ディレクトリツリーは次のようになります。

.
├── javascripts
|   ├── application.coffee
│   └── components
│       └── tags.coffee
└── stylesheets
    ├── application.scss
    └── components
        └── tags.scss

自動初期化

従来のウェブアプリでは、ページの読み込み時にすべてのJSを初期化するのが普通です。ただし、PJAXとTurbolinksを使用すると、要素が常にDOMに追加されたりDOMから削除されたりします。このため、新しいコンポーネントがdomに入るとコードが自動的に検出し、それらに必要なJSをその場で初期化できると非常に便利です。

一貫した命名スキームにより、これを非常に簡単に行うことができます。自動初期化には無数のアプローチがあります。これが1つです:

Initializers = {
  tags: function(el){
    $(el).on("click", "button", function(){  
      // setup component
    });
  }

  // Other initializers can go here
}

// Handler called on every normal and pjax page load
$(document).on("load, pjax:load", function(){
  for(var key in Initializers){
    $("." + key + "-component").each(Initializers[key]);
  }
}

これにより、CSSも向上します!

Webページでの競合の原因はJavaScriptだけではありません。 CSSはさらに悪化する可能性があります!幸い、私たちの気の利いた名前空間システムにより、競合のないCSSの記述もはるかに簡単になります。 SCSSではさらに優れています:

.tags-component {
  input { ... }
  button { ... }
  span { ... }
}

  1. ソーシャル メディア プロフィール用の印刷可能な QR コードを生成する

    最近では、ソーシャル メディアに参加していない人のことを想像するのは困難です。私たちはソーシャル メディア アカウントを使用して自分自身を宣伝します。つまり、私たちについてもっと知りたい人は、ソーシャル メディア アカウントにアクセスできます。 ソーシャル メディアのリンクを電子メールで共有することがよくあります。また、ID やユーザー名を他のユーザーと共有することもあります。リンクがソーシャル メディア アカウントにアクセスしてもらう最も簡単な方法であることは間違いありませんが、印刷媒体や履歴書からアクセスしてもらいたい場合はどうでしょうか。ユーザー名を提供することは、読者の手間がかかるた

  2. CCleaner for Android のレビュー:電話を修理する

    スマートフォンは、私たちが他の人とつながることを可能にするだけでなく、私たちの財布、ガイド、娯楽、そして多くの人にとって仕事の源になっているため、私たちが持っている最も重要で価値のあるものです.新品のスマートフォンを手にしたときは誰もがワクワクしますが、数か月使用した後は同じようには感じません。素早いナビゲーション、時代を超越した応答、マイクロ秒のアプリ起動機能は消えてしまい、ラグの問題、アプリを開くための待ち時間の増加などに置き換えられたようです. いいえ、今はスマートフォンを買い替える時ではなく、最適化する時です。すべての機械にはメンテナンスが必要であり、スマートフォンも例外ではありませ