Как я получаю доступ к параметрам строки запроса в asp.net mvc?

ClojureScript поддерживает оптимизацию :advanced, в которой Google Closure Compiler будет переименовывать, вставлять или исключать (неиспользуемые) функции для реализации минимизации. Короче говоря, имя функции, которую вы хотите найти, в общем случае просто больше не существует в :advanced.

Из-за этого ClojureScript resolve является средством времени компиляции (макрос, требующий буквально заключенного в кавычки символа).

Если вы используете :simple или самодостаточный ClojureScript, вам доступны дополнительные параметры, поскольку необходимая поддержка сохраняется во время выполнения. Например, у Планка есть planck.core/resolve, который ведет себя как у Clojure resolve. Подобный подход возможен в Lumo , и аналогичные средства могут быть созданы при использовании :simple.

В общем, хотя, учитывая :advanced, если вам нужно отобразить строки в набор функций, вам нужно каким-то образом организовать статическое отображение, построенное во время компиляции для поддержки этого (набор функций должен быть известен [ 1130] априори , во время компиляции).

Если у вас есть пространство имен (имя которого статически известно во время компиляции), которое определяет функции, которые должны вызываться динамически через строки, вы можете рассмотреть использование ns-publics:

cljs.user=> (ns foo.core)

foo.core=> (defn square [x] (* x x))
#'foo.core/square
foo.core=> (in-ns 'cljs.user)
nil
cljs.user=> (when-some [fn-var ((ns-publics 'foo.core) (symbol "square"))]
               (fn-var 3))
9

[1136 ] Это будет работать в соответствии с :advanced. Отображение, построенное в ns-publics, является статическим; построен во время компиляции. Если у вас есть несколько пространств имен, которые требуют такой обработки, вы можете merge сделать несколько вызовов ns-publics, чтобы построить большую карту.

Преимущество этого подхода в том, что используемый код довольно короткий и не требует значительного обслуживания. Недостатком является то, что он сбрасывает все открытые переменные пространства имен (foo.core в этом примере) в ваш сгенерированный код (и сгенерированный код для vars является довольно многословным). Другим недостатком является то, что вам необходимо статически знать пространство имен, задействованное во время компиляции.

Если вам нужно дополнительно минимизировать размер сгенерированного кода, вы можете просто создать / поддерживать простую статическую карту из строки в значение функции, как в

(def fns {"square" foo.core/square})

, и использовать ее соответствующим образом, поддерживая ее в актуальном состоянии, как ваша кодовая база развивается.

Другой вариант - пометить функции, к которым вам нужен доступ, с помощью мета ^:export, а затем вызвать эти функции с помощью взаимодействия JavaScript. Например, если вы определяете функцию таким образом

 (defn ^:export square [x] (* x x))

, то вы можете использовать strings / interop для поиска функции и вызова ее во время выполнения. Вот пример:

 ((goog.object/getValueByKeys js/window #js ["foo" "core" "square"]) 3)

Использование ^:export и :advanced описано здесь . Если вы знаете, что используете :simple или меньше, вы можете просто использовать взаимодействие JavaScript для вызова интересующих функций, без необходимости использовать ^:export.

Обратите внимание, что не существует общего решения, которое позволило бы вам искать функцию по имени во время выполнения в :advanced, не добавляя какой-либо аспект этой функции в ваш код во время компиляции. (Фактически, если на функцию не ссылаются так, как статически компилятор Google Closure может видеть, реализация функции будет полностью исключена как мертвый код.) В приведенном выше ns-publics захватывает все переменные для пространства имен при компиляции время, когда вы катите свою собственную карту поиска, устанавливает статический код для ссылки на значение функции и использует статическое расположение ^:export, чтобы имя функции сохранялось во время выполнения.

39
задан Alexander Taran 9 December 2016 в 20:29
поделиться

4 ответа

до сих пор лучший способ, которым я выяснил, состоит в том, чтобы создать копию ViewContext.RouteData.Values и ввести значения QueryString в нее. и затем измените его перед каждым ActionLink использование. все еще пытаясь выяснить, как использовать .Union() вместо того, чтобы изменить словарь все время.

<% RouteValueDictionary   tRVD = new RouteValueDictionary(ViewContext.RouteData.Values); %>

<% foreach (string key in Request.QueryString.Keys )
    {
         tRVD[key]=Request.QueryString[key].ToString();
    } %>

<%tRVD["SortBy"] = "Name"; %>
                <%= Html.ActionLink("Name", "Index", tRVD)%>
29
ответ дан Amirhossein Mehrvarzi 27 November 2019 в 02:45
поделиться
<%= Html.ActionLink("Name", "Index", new { SortBy= "Name", Filter="Something"}) %>

Для сохранения querystring Вы можете:

<%= Html.ActionLink("Name", "Index", 
     String.IsNullOrEmpty(Request.QueryString["SortBy"]) ? 
        new { Filter = "Something" } : 
        new { SortBy=Request.QueryString["SortBy"], Filter="Something"}) %>

Или если у Вас есть больше параметров, Вы могли бы создать ссылку вручную при помощи взятия Request.QueryString во внимание.

8
ответ дан Mehrdad Afshari 27 November 2019 в 02:45
поделиться

Используйте ] ActionLinkCombined вместо ActionLink

        public static string ActionLinkCombined(this HtmlHelper htmlHelper, string linkText, string actionName,
                                            object routeValues)
    {
        var dictionary = new RouteValueDictionary();
        foreach (var pair in htmlHelper.ViewContext.Controller.ValueProvider)
            dictionary[pair.Key] = pair.Value.AttemptedValue;
        if (routeValues != null)
        {
            foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(routeValues))
            {
                object o = descriptor.GetValue(routeValues);
                dictionary[descriptor.Name] = o;
            }
        }
        return htmlHelper.ActionLink(linkText, actionName, dictionary);
    }
4
ответ дан 27 November 2019 в 02:45
поделиться

Мое решение похоже на qwerty1000's. Создал метод расширения, ActionQueryLink , который принимает те же основные параметры, что и стандарт ActionLink . Он протекает через запрос .QueryString и добавляет какие-либо параметры, найденные в словаре Routevalues ​​, которые еще не присутствуют (поэтому мы можем перезаписать исходную строку запроса, если это необходимо).

Чтобы сохранить существующую строку, но не добавлять какие-либо клавиши. Использование будет:

<%= Html.ActionQueryLink("Click Me!","SomeAction") %>

, чтобы сохранить существующую строку и добавить новые ключи, которые пользователь будет:

<%= Html.ActionQueryLink("Click Me!","SomeAction", new{Param1="value1", Param2="value2"} %>

код ниже для двух использований, но это должно Будьте довольно легко добавить другие перегрузки, чтобы соответствовать другому ActionLink расширения по мере необходимости.

    public static string ActionQueryLink(this HtmlHelper htmlHelper,
        string linkText, string action)
    {
        return ActionQueryLink(htmlHelper, linkText, action, null);
    }

    public static string ActionQueryLink(this HtmlHelper htmlHelper, 
        string linkText, string action, object routeValues)
    {
        var queryString =
            htmlHelper.ViewContext.HttpContext.Request.QueryString;

        var newRoute = routeValues == null 
            ? htmlHelper.ViewContext.RouteData.Values 
            : new RouteValueDictionary(routeValues);

        foreach (string key in queryString.Keys)
        {
            if (!newRoute.ContainsKey(key)) 
                newRoute.Add(key, queryString[key]);
        }
        return HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext,
            htmlHelper.RouteCollection, linkText, null /* routeName */, 
            action, null, newRoute, null);
    }
12
ответ дан 27 November 2019 в 02:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: