Я кодирую в ASP.NET MVC 5.2 и использую jQuery в качестве основной библиотеки скриптов. Однако у меня есть небольшая проблема с несоответствием между _Layout и представлениями, которые используют этот макет.

По сути, это выглядит так

  1. _Layout содержит некоторые скрипты, которые необходимо запустить (начальное подключение, индикатор выполнения, экран-заставка и т. Д.)
  2. При наследовании представления есть сценарий, который необходимо запустить (уникальный для этого представления)
  3. _Layout имеет дополнительные сценарии, которые необходимо запускать после уникальных сценариев представления.

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

Я пробовал обещать, и это меня расстраивает. Я пробовал события, и это не особо помогает, потому что я не могу понять, к чему привязать события. Мне сказали не прикреплять их к $(document), но на самом деле это одна из единственных вещей, которые будут совместно использоваться представлением и макетом.

Я понимаю, что глобальные объекты не считаются хорошими в javascript, но на данный момент я не уверен, какие еще варианты у меня есть, чтобы убедиться, что все выполняется в правильном порядке.

Обновить

Проблема больше в «инструментарии», чем во времени выполнения. Это правда, что когда фактическое представление загружается и запускается, все оно помещается в одну большую счастливую страницу и будет работать нормально. Проблема в основном в том, что мне нужно разделить логику в инструментарии (Visual Studio), чтобы он не выдавал ошибок и не запутался.

Так что, полагаю, правильнее было бы сказать, что это псевдопроблема.

Я попытался разделить подобную логику, но я думаю, что это просто еще один способ объявления глобального объекта. Я почерпнул идею из библиотеки Q.js.

Tasks.js

(function(definition) {
    // assign the task system
    tasks = definition();
})(function() {
    var list = [];

    function tasks() {

    };

    tasks.start = start;
    tasks.enqueue = enqueue;
    /*
     * start the task queue.
     */
    function start() {
        // make sure to raise a started event for things that need
        // to monitor it.
        $(this).trigger("started");
    };
    function enqueue(f) {
       // add the potential function to the queue to be processed later.
       list.push(f);
       $(this).trigger("enqueue", { item: f });
    };

    return tasks;

});

Пример использования

$(function(){
  $(tasks).on("started", function(){
    console.log("event called");
  });
  
  console.log("tasks", tasks);
  tasks.start();
});
3
Ciel 9 Июл 2014 в 20:53

2 ответа

Лучший ответ

Есть несколько способов сделать это:

  1. Используйте RequireJs для определения задач как модуля, а затем:

    require(['tasks'], function(tasks){
      $(tasks).on("started", function(){
        console.log("event called");
      });
    
      console.log("tasks", tasks);
      tasks.start();
    });
    
  2. Используйте глобальный объект, но в пространстве имён:

    Ciel = Ciel || {};
    Ciel.tasks = Ciel.tasks || function(){
        var list = [];
        ...
    };
    
  3. Свяжите свои данные с конкретным элементом dom:

    <div class="ciel-tasks"></div>
    
    ...
    
    $(function() { $('.ciel-tasks').each(function() {
        var tasks = $(this);
        ...
    });
    
1
StriplingWarrior 9 Июл 2014 в 17:35

Не совсем понятно, что вы описываете. С точки зрения JavaScript не существует таких вещей, как «_Layout» и «Наследование представления». Браузеру доставляется только получившийся DOM. Любой код JavaScript в этой DOM может работать с чем угодно еще в этой DOM. Так что я не уверен, какое отношение все это имеет к глобальному пространству имен, событиям, $(document) и т. Д. Возможно, вы слишком усложняете проблему, допуская несоответствие между вашими взглядами, когда на стороне клиента такого несоответствия нет?

_Layout имеет дополнительные сценарии, которые необходимо запускать после уникальных сценариев представления.

Похоже, это просто вопрос обеспечения обратных вызовов для операций, чтобы они выполнялись внутри в правильном порядке. Например, если желаемый порядок:

  • Макет выполняет initializeLayout()
  • Просмотр выполняет initializeView()
  • Макет выполняет completeLayout()

Затем вы можете передавать их друг другу как обратные вызовы, и функции могут внутренне выполнять эти обратные вызовы. Итак, в вашем макете у вас может быть что-то вроде этого на самом верху (например, в заголовке, если это до визуализации представления):

<script type="text/javascript">
    function initializeView(){} // placeholder for view-specific initialization
</script>

Затем внизу с остальными вашими скриптами:

initializeLayout();
initializeView(completeLayout);

Это дает вашим представлениям возможность перезаписать эту функцию initializeView. Если представление определяет свою собственную функцию с именем initializeView, тогда эта будет выполняться вместо заполнителя, определенного в макете (помня, что макет и представление - все это одна страница для JavaScript) .

(Это также предполагает, что вы где-то еще определили функцию completeLayout, поскольку это то, что вы хотите выполнить после инициализации представления.)

Затем, на ваш взгляд, вы можете определить эту функцию перезаписи:

function initializeView(callback) {
    // do some stuff...

    if (typeof callback == 'function') {
        callback();
    }
}

Это выполнит ваш код инициализации представления, а затем, когда он будет завершен, вызовет обратный вызов, который был предоставлен макетом, поэтому макет затем выполнит свой код инициализации после просмотра. (Естественно, если какой-либо из этого «инициализирующего» кода является асинхронным, вы захотите вызывать обратные вызовы в ответ на эти асинхронные обратные вызовы и т. Д.)

1
David 9 Июл 2014 в 17:07