C# 用の jquery クローンを作成しています。現在、すべてのメソッドが拡張メソッドになるようにセットアップしているので、IEnumerable<HtmlNode>
既にHtmlAgilityPack
. 状態を保存せずに逃げることができると思っていました...しかし、jQueryには2つのメソッドが.andSelf
あり.end
、最近一致した要素を内部スタックから「ポップ」することに気付きました。列挙型ではなく SharpQuery オブジェクトで常に動作するようにクラスを変更すると、この機能を模倣できますが、まだ問題があります。
JavaScript では Html ドキュメントが自動的に提供されますが、C# で作業する場合は明示的に読み込む必要があり、必要に応じて複数のドキュメントを使用できます。$('xxx')
呼び出すと、本質的に新しい jQuery オブジェクトを作成し、空のスタックで新たに開始しているように見えます。C# では、Web からドキュメントをリロード/再取得したくないため、これを行いたくありません。代わりに、SharpQuery オブジェクトまたは HtmlNodes のリストに一度ロードします (開始するには DocumentNode が必要です)。
jQueryのドキュメントでは、彼らはこの例を示しています
$('ul.first').find('.foo')
.css('background-color', 'red')
.end().find('.bar')
.css('background-color', 'green')
.end();
()
演算子をオーバーロードできないため、初期化メソッドはありません。sq.Find()
代わりに、ドキュメントのルートで動作し、本質的に同じことから始めます。sq.Find()
しかし、人々は1 行で書き込もうとし、その後sq.Find()
どこかで書き込もうとし、(当然のことながら) ドキュメントのルートで再び動作することを期待します... しかし、私が状態を維持している場合、あなたは最初の呼び出しの後にコンテキストを変更しただけです。
では、API をどのように設計すればよいでしょうか? すべてのクエリがスタックをリセットする別のメソッドを追加するInit
必要がありますか (しかし、それから強制的に開始するにはどうすればよいでしょうか?)、またはReset()
、行の最後に呼び出さなければならない a を追加しますか? 代わりにオーバーロードして、[]
それから始めるように伝えますか? 「忘れてください、とにかく誰も状態保存関数を使用していません」と言いますか?
基本的に、その jQuery の例を C# でどのように記述しますか?
sq["ul.first"].Find(".foo") ...
落とし穴:[]
プロパティを悪用します。sq.Init("ul.first").Find(".foo") ...
落とし穴: 奇妙な「初期化」メカニズムを追加しない限り、プログラマーに Init を開始することを実際に強制するものは何もありません。ユーザーは最初から試してみて.Find
も、期待した結果が得られない可能性があります。また、Init
前者Find
もスタックをリセットすることを除いて、とにかくほとんど同じです。sq.Find("ul.first").Find(".foo") ... .ClearStack()
欠点: プログラマーがスタックをクリアするのを忘れる可能性があります。できません。
end()
実装されていません。2 つの異なるオブジェクトを使用します。
おそらくHtmlDocument
、すべてのクエリを開始するベースとして使用すると、その後のすべてのメソッドSharpQuery
が連鎖可能なオブジェクトを返します。このように、 はHtmlDocument
常に初期状態を維持しますが、SharpQuery
オブジェクトは異なる状態になる場合があります。これは残念ながら、たくさんのものを 2 回 (HtmlDocument に対して 1 回、SharpQuery オブジェクトに対して 1 回) 実装する必要があることを意味します。new SharpQuery(sq).Find("ul.first").Find(".foo") ...
コンストラクターはドキュメントへの参照をコピーしますが、スタックをリセットします。