Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Помню твои статьи против Angular)))
Уже не воюешь теперь?)
Как тогда ни одного комментария в коде, так и сейчас. Вы хоть бы код комментариями покрыли.
Да и если честно код не ахти.
А собственно зачем это тут?
Мало чтоли фреймворков?
Кто будет это использовать?
Кому нужно изучать странный способ определения банальных вещей (это я больше про *.cshtml)?
Основная причина, это типизация, которой так не хватает на JS.
TypeScript?
Так и JS — язык.
Если вам не хватает типизации — почему не взять язык, в котором она есть, зачем городить фреймворк?
Я думал, Вы в рамках framework сравниваете, а так да, Вы правы.
А я не сравниваю, я отвечаю на ваш же тезис о том
что основная причина того, что вы напридумывали во view — это отсутствие типизации в JS
Тезиз был в сравнение TypeScript и Incoding Framework.
В итоге мы пришли к тому, что все приложения строится на языке C# без написания дополнительного JS кода.
Я даже знаю, где я это уже видел — в WebForms. Там тоже серверные компоненты позволяли построить весь интерфейс декларативно…
Так же можно привести в пример и asp.net mvc (Html.TextBoxFor, Html.DropDownFor)
AjaxGet(Url.Dispatcher().AsView("~/Views/Home/AddOrEditHuman.cshtml"))А вы поднимаете этот уровень абстракции обратно.
@Html.Rap().Admin.Tab(setting =>
{
setting.Url = Url.Dispatcher().AsView("~/Views/DiabetesMedication/Index.cshtml");
setting.Title = "Diabetes Medications";
})
@Html.ForGroup(r => r.FirstName).TextBox(control => control.Label.Name = "First name")
Здравствуй, нарушение SoC.
@Html.For(r => r.AgencyId).DropDown(control =>
{
control.Url = Url.Dispatcher().Query<GetSupportServicesForDDQuery>().AsJson();
control.AddClass("selectInput400 firstControl");
})
Мы просто дополнительно передаем атрибуты в качестве параметра в уже существующие «конторолы» asp.net mvc.
Сравнивания с asp.net control такие как, updatepanel, grid и т.д, то надо понимать, что для обработке клиентских сценариев все равно требовалось подписывать на события и писать JS, а мы полностью строим все на сервере (а вот выполняем и там и там)
Попробовал загуглить, но не нашел определения для SoC, Вы имеете ввиду, какую то проблему с безопасностью?
Я имею в виду Separation of Concerns.
Я сравниваю с девэкспрессом, где чертова уйма клиентского поведения реализовывалась самим контролом, и была разработчику недоступна.
AjaxGet(Url.Dispatcher().AsView("~/Views/Home/AddOrEditHuman.cshtml"))
это тоже самое, что и
AjaxGet(Url.Action(«AddOrEditHuman»,«Home»))
Вы сами пишете это поведение, точно так же, как и страницу HTML с помощью тэгов, но не думаете, как они «рисуются» браузером
Нет. В первом случае я явно указываю серверу, какое представление мне нужно, а во втором — я указываю, какой экшн у какого контроллера вызвать. Разная степень информированности о сервере.
Вот это я и называю повышеним абстракции — рисование, не думая. В WebForms действительно была такая идеология. В asp.net MVC от нее отказались.
По мне плюсы, которые я получаю, а именно возможность писать на много меньше кода, покрывают с лихвой это момент, при том условии, что Вам не нужно ничего дополнительно дописывать.
Мы тоже довольно низко-уровневая часть, то есть IML он просто дает функционал, но ничего конкретного не реализовывает к примеру grid, tabs или TextBoxAlertByChange
К сожалению, почти всегда — надо.
Тогда как же вам удалось полностью отказаться от JS?
сам движок, который выполняет IML само собой на JS
… и этот JS программистом никак не контролируется. Вот именно это мне и напомнило старые добрые времена WebForms.
Нету у нас JS программистов
Оно и видно.
Вы говорите, что ваше приложение строится целиком на C#, без написания JS. Как вы реализуете сложную клиентскую валидацию (поле такое-то должно зависеть от полей таких-то и таких-то)? А динамические интерфейсы (если выбрано поле такое-то, показать поля такие-то и такие-то)?
<span class="field-valiion-valid"></span>
@(Html.When(JqueryBind.Change)
.AjaxGet(Url.Dispatcher().Query(new IsEmailUniqueQuery()
{
Email = Selector.Jquery.Self()
}))
.OnSuccess(dsl =>
{
dsl.WithClass("field-valiion-valid").JQuery.Attr.RemoveClass("field-validation-error");
dsl.WithClass("field-valiion-valid").JQuery.Attr
.AddClass("field-validation-error")
.If(() => Selector.Result.For<IncBoolResponse>(r => !r.Value));
})
.AsHtmlAttributes(new {id ="id or you can use TextBoxFor with typed C#"})
.ToTextBox())
public class Validator : AbstractValidator<TCommand>
{
public Validator()
{
var dispatcher = IoCFactory.Instance.TryResolve<IDispatcher>();
RuleFor(r => r.Email) .Must((email) => dispatcher.Query(new IsEmailUniqueQuery() { Email = email }));
}
}
@model FirstAndLastName
@Html.CheckBoxFor(r => r.SomethingElse)
@Html.For(r => r.First).TextBox(control =>
{
control.OnChange = dsl => dsl.With(Html.Selector().Name(r => r.Last))
.JQuery.Attr.AddClass("hide")
.If(() => Selector.Jquery.Self() == "Remove hide from Last" &&
Html.Selector().Name(r => r.SomethingElse));
})
@Html.For(r => r.Last).TextBox()
dsl.With(someSelector).Jquery.Attr.Val(Selector.Incoding.QueryString("test"))
Cценарий проверки email на уникальность по Ajax
Html.When().AjaxGet().OnSuccess().AsHtmlAttributes().ToTextBox(). Событие и цель события разнесены в разные концы, смысл двух последних действий из названия не понятен.class SomeModel
{
[ValidationQuery(typeof(IsEmailUniqueQuery)]
public string Email {get; set;}
}
Html.TextBoxFor(m => m.Email).Validate(v => v.WithQuery<IsEmailUniqueQuery>())
Сценарий зависимых элементов
Ну и в-третьих, это неверный уровень абстрации. Вот как это должно выглядеть на самом деле:
Ну или ad-hoc:
нет очевидной связи с общей отправкой формы
Тут все лучше, но нет никакой возможности оптимизировать получившийся JS-код
впрочем, как мы выясняли, у вас это некому делать.
То, что Вы привели это будет работать в первую очередь на сервер, на клиент надо дописывать Jquery validation и т.д.
Если Вы читали, то увидели, что я привел такой пример «Html.ProjName().Control.Unique(r=>r.Email)»
Проверка email идет сразу после ввода, если Вам нужно после в моменты отправки form, то в incoding framework можно написать validator и в обработчике Submit добавить OnError в котором вызывать Form.Validation.Refresh().
Это примерно, как Nhibernate (или другой ORM), там все уже оптимизировали и своего добавить нельзя, но зато можно не писать SQL
Все же грубите ?)
Нет, это будет работать там, куда вы это напишете. MVC, например, умеет генерить клиентскую валидацию из атрибутов.
Это поддерживается фреймворком или написанный программистом хелпер? Ну и он все равно семантически неверен.
… а все это должно работать само и целиком. Как, собственно, в MVC и работает.
Нет, аргументирую для себя принятые вами решения.
Понятно дело, что fluent validation прекрасно транслирует NotEmpty,NotNull, но к примеру Must уже не получится, а вызов Ajax это тот самый случай.
В framework по мимо IML, есть и набор готовых решений на нем, но для каждого проекта присущи свои особенности.Задача была написать, как язык для решения любых сценариев, так и готовые компоненты.
Это разные сценарии, иногда надо отправить форму и провалидоравать, но так же есть ситуации быстрого реагирования на действия пользователей.
Ваш профиль говорит, о том что кроме как «аргументирую для себя принятые кем то решения» не делаете ничего.
я думаю было бы справедливо предоставить плоды Вашей деятельности?
Что вам мешает самим-то (внутри фреймворка) реализовать аналогичное? Это же тривиальный анализ мета-данных и эмит кода в представление.
Ну то есть программистом. Что, знаете ли, удивительно, учитывая, как много вы говорите о своем фреймворке с точки зрения «уменьшает количество кода». Валидация — один из первых пунктов интереса в таком фреймворке (и именно она съедает ощутимую долю усилий).
.OnError(dsl => dsl.Self().Core().Form.Validation.Refresh())
Нет, спасибо, на «сперва добейся» я не ведусь — особенно учитывая, что моя деятельность в конкретной обсуждаемой области была для конкретного работодателя, и, как следствие, код я вам показать не смогу.
Как Вы можете рассуждать, что надо реализовать, если Вы даже не использовали?
Вы не хотите ничего читать, в статье (и много другого материала об этом) есть описание, как работает валидация
то есть для себя Вы не пишите ни каких инструментов, которые используете от проекта в проекту?
Во-первых, лишний вызов (валидация должна работать прозрачно). Во-вторых, это клиентская валидация или серверная?
BTW, пример такой контрибуции тоже легко находим через мой профиль, который вы, по вашим словам, посмотрели.
public class TestCommand : CommandBase
{
public string NotEmpty { get; set; }
public string Must { get; set; }
public string ThrowFromCommand { get; set; }
public override void Execute()
{
throw IncWebException.For<TestCommand>(command => command.ThrowFromCommand, "Error");
}
public class Validator : AbstractValidator<TestCommand>
{
public Validator()
{
RuleFor(r => r.NotEmpty).NotEmpty();
RuleFor(r => r.Must).Must(s => s != "Test").WithMessage("Value it is 'Test'");
}
}
}
@using (Html.BeginPush(setting => { setting.OnSuccess = dsl => dsl.Utilities.Window.Alert("Success"); }))
{
// work on client (also checking on server) because can translated by Fluent Validation
@Html.ForGroup(r => r.NotEmpty).TextBox(control => { control.Label.Name = "Not Empty"; })
// work ONLY server side
@Html.ForGroup(r => r.Must).TextBox(control => { control.Label.Name = "Value"; })
// work ONLY server side
@Html.ForGroup(r => r.ThrowFromCommand).TextBox(control => { control.Label.Name = "Error"; })
<input type="submit" value="Submit"/>
}
public static class HtmlExtensions
{
public static IDisposable BeginPush<T>(this HtmlHelper<T> htmlHelper, Action<Setting> action)
{
var setting = new Setting();
action(setting);
var url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
return htmlHelper.When(JqueryBind.Submit)
.PreventDefault()
.Submit()
.OnBegin(dsl => dsl.Self().Core().Form.Validation.Parse())
.OnSuccess(dsl =>
{
if (setting.OnSuccess != null)
setting.OnSuccess(dsl);
})
.OnError(dsl => dsl.Self().Core().Form.Validation.Refresh())
.AsHtmlAttributes()
.ToBeginForm(htmlHelper, url.Dispatcher().Push(new TestCommand()));
}
public class Setting
{
public Action<IIncodingMetaLanguageCallbackBodyDsl> OnSuccess { get; set; }
}
}
TypeScript не имеет интеграции с template
а вот и имеет. называется tsx :)
dsl.Self().WithTemplateUrl(Url.Dispatcher().AsView("path")).Html()
и когда человек будет пытаться адаптировать все это под свои (не в HelloWord), то возникнут проблемы, иногда не решаемые и тогда начнется…
Incoding Framework — Get started