Я думаю, что основным камнем преткновения, с которым вы здесь сталкиваетесь, является то, что вы пытаетесь избежать необходимости иметь только один объект SharpQuery
для каждого документа. Это не так, как работает JQuery; в общем, объекты jQuery неизменны. Когда вы вызываете метод, который изменяет набор элементов (например, find
или end
или add
), он не изменяет существующий объект, но возвращает новый:
var theBody = $('body');
// $('body')[0] is the <body>
theBody.find('div').text('This is a div');
// $('body')[0] is still the <body>
(см. документацию end
для получения дополнительной информации)
SharpQuery должен работать так же. После создания объекта SharpQuery с документом вызовы методов должны возвращать новые объекты SharpQuery
, ссылающиеся на другой набор элементов того же документа. Например:
var sq = SharpQuery.Load(new Uri("http://api.jquery.com/category/selectors/"));
var header = sq.Find("h1"); // doesn't change sq
var allTheLinks = sq.Find(".title-link") // all .title-link in the whole document; also doesn't change sq
var someOfTheLinks = header.Find(".title-link"); // just the .title-link in the <h1>; again, doesn't change sq or header
Преимущества этого подхода несколько. Поскольку sq
, header
, allTheLinks
и т. Д. Являются одним и тем же классом, у вас есть только одна реализация каждого метода. Тем не менее каждый из этих объектов ссылается на один и тот же документ, поэтому у вас нет нескольких копий каждого узла, и изменения узлов отражаются в каждом SharpQuery
объекте в этом документе (например, после allTheLinks.text("foo")
, someOfTheLinks.text() == "foo"
.) .
Реализация end
и других основанных на стеке манипуляций также становится легкой. Поскольку каждый метод создает новый, отфильтрованный SharpQuery
объект из другого, он сохраняет ссылку на этот родительский объект (allTheLinks
до header
, header
до sq
). Тогда end
так же просто, как вернуть новый SharpQuery
, содержащий те же элементы, что и родительский, например:
public SharpQuery end()
{
return new SharpQuery(this.parent.GetAllElements());
}
(или, тем не менее, ваш синтаксис встряхивает.)
Я думаю, что этот подход даст вам наиболее jQuery-подобное поведение с довольно простой реализацией. Я определенно буду следить за этим проектом; это отличная идея.