Как использовать сценарии @section в частичном представлении MVC.Core - PullRequest
0 голосов
/ 07 июля 2019

В ASP.NET Core MVC можно определить секцию скрипта для страницы следующим образом:

@section scripts {
    <script>
        alert('hello');
    </script>
}

А если макет содержит:

@RenderSection("Scripts", required: false)

Ваш скрипт будет обработан. Это удобно в каждом примере, чтобы гарантировать, что сценарии будут отображаться после всех включений javascript, таких как jQuery.

Но как сделать скрипт в частичном представлении?

Ответы [ 3 ]

3 голосов
/ 07 июля 2019

Разделы не работают в частичных представлениях, и это по замыслу. Вы можете использовать несколько пользовательских помощников для достижения аналогичного поведения, но, честно говоря, ответственность за включение необходимых сценариев лежит на представлении, а не на частичном. Я бы порекомендовал использовать раздел @scripts на главном экране, чтобы не беспокоиться о скриптах по частям.

0 голосов
/ 08 июля 2019

Обычно это плохая идея, потому что вы не связываете / не минимизируете свои скрипты.

@ ErikPhilips, это не правда, представьте, что я хочу определенный код JavaScript, который будет работать только в этой части. почему я должен связать его и импортировать по всему приложению? А для минимизации я могу создать свой миниатюрный файл машинописи и импортировать его в частичную часть моего блока скриптов.

представьте, что мне нужен определенный код JavaScript, который будет выполняться только в этом фрагменте.

Сценарий не будет запускаться только в этой части , он будет запускаться для всей страницы . Это код на стороне клиента, доставляемый за один HTTP-вызов (при условии обычного использования, потому что вы ничего не указали). Рассмотрим частичное:

@Model SomeModel
<div class='my-component'>
<div>
<script>
  $('.my-component').css('width', model.Width);
</script>

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

Вместо этого вы можете создать один файл сценария и использовать data- * attribute для хранения информации о конфигурации и позволить единому сценарию понять это (как делают многие МНОГИЕ библиотеки, например, начальная загрузка):

<div class='my-component green' data-config='{ "width": 200, "height": 200 }'>
</div>

затем в одном файле сценария:

$(document).ready(function(){
  $('.my-component').each(function(){
    var $this = $(this);
    var config = $this.data('config');
    $this.css("width", config.width);
    $this.css("height", config.height);
  });
});

почему я должен связать это

Потому что тогда автоматически кэшируется браузером. Это значит меньше, чтобы загрузить каждый экземпляр. Учтите следующее:

<div class='my-component'>
<div>
<script>
  // lots of scripts say 100-200 lines of it.
</script>

Каждый раз, когда клиент посещает какую-либо страницу, он должен загружать, вероятно, один и тот же точный код каждый раз, возможно, несколько раз на страницу. Это требует как пропускной способности клиента, так и пропускной способности сервера, что необязательно.

и импортировать по всему приложению?

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

А для минимизации я могу создать минимизированный мой машинописный файл и импортировать его в частичное внутри моего блока скриптов.

Тогда зачем вообще иметь сценарий в частичном.

Рекомендуемое чтение: Разделение вашего HTML, CSS и JavaScript

0 голосов
/ 07 июля 2019

Вот решение:

На странице макета:

@Html.PageScripts()

Частично:

@using (Html.BeginScripts())
{
 <script>
   alert('hello');
 </script>
}

И вспомогательный класс для MVC.core

using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.IO;

namespace MyProjectNamespace
{
    public static class HtmlHelpers
    {
        private const string ScriptsKey = "DelayedScripts";

        public static IDisposable BeginScripts(this IHtmlHelper helper)
        {
            return new ScriptBlock(helper.ViewContext);
        }

        public static HtmlString PageScripts(this IHtmlHelper helper)
        {
            return new HtmlString(string.Join(Environment.NewLine, GetPageScriptsList(helper.ViewContext.HttpContext)));
        }

        private static List<string> GetPageScriptsList(HttpContext httpContext)
        {
            var pageScripts = (List<string>)httpContext.Items[ScriptsKey];
            if (pageScripts == null)
            {
                pageScripts = new List<string>();
                httpContext.Items[ScriptsKey] = pageScripts;
            }
            return pageScripts;
        }

        private class ScriptBlock : IDisposable
        {
            private readonly TextWriter _originalWriter;
            private readonly StringWriter _scriptsWriter;

            private readonly ViewContext _viewContext;

            public ScriptBlock(ViewContext viewContext)
            {
                _viewContext = viewContext;
                _originalWriter = _viewContext.Writer;
                _viewContext.Writer = _scriptsWriter = new StringWriter();
            }

            public void Dispose()
            {
                _viewContext.Writer = _originalWriter;
                var pageScripts = GetPageScriptsList(_viewContext.HttpContext);
                pageScripts.Add(_scriptsWriter.ToString());
            }
        }
    }
}

Совет: импортируйте свой помощник по классам в _ViewImports.cshtml, чтобы вы могли использовать его во всех представлениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...