T4MvcJs — строготипизированный яваскрипт-хелпер для URL

Не так давно я уже писал о решении проблемы «магических строк» в яваскрипте, примером таких строк могут служить url экшенов («/Home/Index?name=John&lastname=Doe»)

В разор-вьюшках проблему написания урлов «напрямую» можно решить с помощью T4Mvc: @Url.Action(MVC.Actions.Home.Index(«John», «Doe)). Проблема в том, что этот код — серверный, и написать что-то подобное в script.js — не получится.
В предыдущем посте я уже предлагал решение проблемы, однако(об этом я также писал) в нём была существенная недоработка. Новая версия T4MvcJs эти недоработки устраняет, и в результате мы, как и прежде, спокойно сможем писать в яваскрипт файлах что-то вроде: MvcActions.Home.Index(«John», «Doe»), и это будет полностью клиентский код.

Показать недоработку, присутствовавшую ранее, проще всего на примере:

public class HomeController : Controller    {
        public ActionResult Index(int id)   {
            return View();
        }
}

Простейший контроллер. Чтобы сослаться на него из яваскрипта достаточно написать: MvcActions.HomeController.Index(5);
В результате в старой реализации мы бы получили: «/home/index?id=5»

Результат удовлетворителен, но не забываем, что в MVC по-умолчанию есть прописанный маршрут:

routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });

И поэтому более корректным урлом был бы: «/home/index/5». Собственно, в новой версии эта проблема решена. Работает это, естественно, не только для Id, но и для любого другого маршрута, который вы статически задали в Global.asax.

Использовать T4MvcJs проще простого — «Install-Package T4MvcJs». После этого в проекте появится файл Scripts/T4MvcJs/T4MvcJs.tt, по которому сгенерируется T4MvcJs.js. Этот файл и надо добавить в ваш Layout/MasterPage:

<script src="/Scripts/T4MvcJs/T4MvcJs.js" type="text/javascript"></script>

Напомню, что T4MvcJs также создает яваскрипт-хэлперы для публичных констант, объявленных в контроллерах (с этим в предыдущей версии тоже была небольшая проблема, которая успешно решена в новой версии).

P.S. Остается вопрос, надо ли выкладывать исходники на codeplex, и стоит ли это постить на хабр/gotdotnet? :)

Опубликовать в Facebook
Опубликовать в Google Plus

6 комментариев

  1. Привет.
    А не лучше ли для решения подобных проблем, просто получше организовать свой javascript-код?
    То есть не пытаться воспроизводить url-ы внутри js-файлов, а просто пробрасывать этот урл внутрь js.
    Тогда код инциализации js-модуля на странице будет выглядеть как то так:
    App.module.init(@MVC.Actions.Home.Index())

    Да, конечно, немного js-кода инициализации на самой странице это уже не совсем unobrusive js.

    Что думаешь по этому поводу?

  2. В моём случае инициализация js-модулей происходит из js-модуля :)
    Ну и изначально у меня эта проблема возникла при генерации параметризованных урлов типа «/articles/getInfo?articleId=10» (допустим, аякс-подгрузка частей контента, «10» — динамический айдишник). В этом случае пробросить @MVC.Actions.Home.Index() — недостаточно, надо как-то параметры туда пихать.
    С этой проблемой, кстати, и при написании js прямо во вьюшке справится нетривиально, это в предыдущем посте было.

    > А не лучше ли для решения подобных проблем, просто получше организовать свой javascript-код?
    Этот подход очень похож на собственно T4MVC. Ведь можно «получше организовать» вьюшки, чтобы урлы к ним приходили как часть ViewModel — и T4MVC не нужен :) Но его использование часто удобнее (хоть и строго говоря нарушает MVC-принцип: вью не обращается ни к чему, кроме модели).

  3. Brian, thanks for your input on that problem.
    I’ve recently refactored T4MVCJS to actually use the source of T4MVC, so everything that it handles, would be handled by T4MvcJs as well.
    Areas though required some additional effort, they are working since ver. 1.0.10 of T4MVCJS and you could get it via NuGet.

    Btw, complete source code is now opensourced on Codeplex

  4. Shaddix, this is exactly what I was looking for, thankyou! We don’t need RenderActionMethods because all our requests are done with POST (for anti-CSRF). So we just go with RenderActionNames, which gives us access to the controller and action names.

    For anyone else wanting to use this (excellent) piece of kit, I had to

    1) change the namespace of T4Proxy to suit my project namespace

    2) fix a compile error on Line 14 of T4Proxy: insert a call to .RegisterRoutes(routes)

    (this was done with the install provided by NuGet, ymmv).

  5. Hmm, the form stripped everything between my angle brackets. The fix on Line 14 should be something like:

    YourApplicationClass.RegisterRoutes(routes);

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *