2013-07-22 3 views
8

Я использую requirejs + jquery + jqueryui. Я прочитал TONS примеров того, как это сделать. Я думаю, что понимаю различные подходы, и мне кажется, что моя настройка должна работать правильно. Тем не менее, я иногда получаю $ .widget не указан ошибка в моих настраиваемых модулях, которые зависят от jquery-ui. Это боль, потому что это противоречиво и трудно воспроизвести, поэтому мне трудно проверить альтернативные подходы.

Я не убираю все мои плагины jquery, потому что их много. Вместо этого я загружаю jquery с помощью отдельного вызова requirejs. Затем, в обратном вызове, я загружаю остальную часть своего материала. Таким образом, мне не нужно поддерживать список прокладок для всех моих jquery-плагинов.

Для jquery-ui я использую прокладку, чтобы она зависела от jquery. Затем все мои пользовательские модули, которые используют фабрику виджета, имеют «jquery-ui» в своем списке зависимостей.

В моих шаблонах ...

requirejs.config({ 
    baseUrl: ATHLETE.siteConfig.jsBaseUrl, 
    paths: { 
     'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min', 
     'jquery-ui': '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min' 
    }, 
    shim: { 
     "jquery-ui": ['jquery'] 
    }, 
    waitSeconds: 15 
}); 

requirejs(['jquery'], function($) { 
    requirejs(['site'], function() { 
     requirejs(['mypage']); 
    }); 
}); 

Обратите внимание, что я загрузки site.js перед тем mypage.js. У них есть общие зависимости. В моей конфигурации сборки я исключаю site.js из mypage.js, поэтому общие зависимости скомпилируются в site.js, а не mypage.js. Поэтому мне нужно полностью загрузить site.js перед загрузкой mypage.js, иначе я могу попытаться загрузить эти общие зависимости отдельно.

Вот пример пользовательского модуля, который зависит от jquery-ui.

define([ 
    'jquery', 
    'jquery-ui' 
],function($) { 
    $.widget('ui.viewAllSponsorsWidget', $.ui.dialog, { 
     options: { 
      autoOpen: false, 
      dialogClass: 'view-all-sponsor-dialog-wrap', 
      draggable: false, 
      modal: true, 
      resizable: false, 
      width: 370, 
      height: 400 
     } 
    }); 
}); 

Ошибка $ .widget не определен вызывается 5-й линии этого и подобных пользовательских модулей шахты. Опять же, это действительно непоследовательно и трудно воспроизвести. Чаще всего я НЕ получаю ошибку, даже когда я очищаю свой кеш. Может ли кто-нибудь подумать о том, что строка 5 может быть выполнена, прежде чем jquery-ui будет полностью загружен?

ОБНОВЛЕНИЕ 16 августа 2013

Я был в состоянии отследить это вниз немного больше. Я создал простой модуль, который зависит от jquery и jquery-ui.

define([ 
    'jquery', 
    'jquery-ui' 
],function($) { 
    console.log('$.widget is defined? ' + Boolean($.widget)); 
    console.log('jQuery.widget is defined? ' + Boolean(jQuery.widget)); 
}); 

Выход этого заключается в следующем:

LOG: $.widget is defined? false 
LOG: jQuery.widget is defined? true 

Так или иначе глобальный объект JQuery имеет виджет определен, но копия предоставляется мне requirejs нет.

+0

Когда не удается загрузить jquery-ui, есть ли в консоли ошибка пути? Смотрите также это: http://stackoverflow.com/questions/17026036/require-js-bug-random-failed-to-load-resource/17044595#17044595 – explunit

ответ

3

Эти ответы немного устарели. Надеюсь предложить немного обновленного ответа. JQuery UI теперь поставляется с поддержкой AMD построен. Вы можете просто получить его с помощью

bower install jquery-ui 

, а затем в requirejs.config просто добавить jquery_ui к путям секции {}. Никакой прокладки больше не требуется.

Если вы хотите загрузить только небольшой подраздел jquery-ui, который вам нужен, установите bower install jquery-ui, а затем используйте инструмент построения, который requirejs предоставляет для создания пакета. В противном случае, если вы только попытаетесь импортировать один отдельный файл, то каждый из файлов jquery-ui попытается загрузить их зависимости, и вы получите такие вещи, как «виджет не определен» или «не можете найти файл widget.js» и т. Д. Я сделал короткую запись здесь: https://hendrixski.wordpress.com/2015/04/17/adding-only-the-parts-of-jquery-ui-that-you-need-into-your-requirejs-project/

Надеюсь, что это поможет.

2

Изменить подкладку к этому:

shim: { 
    'jquery-ui': ['jquery'] 
} 

Вот example кучу конфигураций Require.js для популярных библиотек.

+0

Пробовал, что не помогло. Однако экспорт не нужен, поэтому я все равно обновил код по вашему предложению. К сожалению, это не решение моей проблемы. – Dustin

+0

Я думаю, что реальное решение состоит в том, чтобы закрепить все ваши плагины jQuery, которые зависят от jQueryUI. –

+0

Если вы посмотрите мое последнее обновление, я смог реплицировать проблему без использования каких-либо плагинов jquery. Только с использованием jquery, jquery-ui и настраиваемого модуля, который зависит от них. – Dustin

0

Я думаю, что у меня есть решение моей проблемы. Хотя, поскольку эту проблему трудно воспроизвести, я собираюсь подождать некоторое время, прежде чем «принять» свой собственный ответ как правильно. Кроме того, мой ответ не загружает jquery с помощью requirejs. Я не вижу причин, почему это имеет значение для меня. Но если кто-нибудь увидит способ выполнить это, не загружая jquery в отдельный тег сценария, дайте мне знать.

Поскольку jQuery определяет себя как именованный модуль AMD, я могу просто загрузить его синхронно сначала, используя стандартный тег сценария, прежде чем я сделаю какой-либо материал requirejs. Затем я также удаляю запись своих путей для jquery, так как она уже загружается под именем «jquery» к этому моменту. Делая это, requirejs возвращает мне правильную «копию» jQuery, и все работает. Мне также нужно использовать jQuery.noConflict, потому что я использую Garmin Communicator, который зависит от Prototype. Итак, вот мой обновленный код, опуская нерелевантные части.

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
<script type="text/javascript">$.noConflict();</script> 
<script type="text/javascript"> 
requirejs.config({ 
    baseUrl: ATHLETE.siteConfig.jsBaseUrl, 
    paths: { 
     'jquery-ui': '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min' 
    }, 
    shim: { 
     "jquery-ui": ['jquery'] 
    }, 
    waitSeconds: 15 
}); 
requirejs(['mymodule']); 
</script> 

И мои модули все еще может зависеть от JQuery и JQuery-интерфейса, как обычно:

define([ 
    'jquery', 
    'jquery-ui' 
],function($) { 
    $.widget('ui.mycoolwidget', ...); 
}); 
+0

Это не сработало. :(По-видимому, из-за спорадического характера проблемы, он просто решил уйти по очереди, а затем вернулся. Было совпадением, что проблема остановилась, когда я сделал это последнее изменение. – Dustin

3

была аналогичная проблема была третья часть управления ASP.NET были угон JQuery определить.

$ telerik. $ = JQuery.noConflict();

Хотя сценарий очистить себя, хвост сценария JQuery эффективно переписал мой RequireJS отображение

если (TypeOf определить === "функция" & & define.amd) { определить ("JQuery", [ ], function() {return jQuery;}); }

RequireJS задерживает загрузку сценариев, и RadScriptManager будет продолжать вводить скрипты под тегом формы, чтобы были выделены странные проблемы гонки.

Для некоторых запросов, $ был от моей карты и был глобальным Другие запросы $ был $ Telerik. $ И не был глобальным, и другая версия

Чтобы решить мою проблему, я откатить до версии JQuery Telerik элементы управления использовали и жестко закодировали его в теге scrip, чтобы гарантировать, что он всегда доступен, а затем отключил Telerik от загрузки собственного JQuery. Не AMD, но работает достаточно хорошо для меня.

0

Если вы хотите переопределить какой-либо метод jQuery-ui, то лучшим является использование метода Initjs init, это гарантирует, что в каждом модуле, который включает jQuery-ui, используется тот же модифицированный код.

использовать Shim как этого

'jquery-ui': { deps: ['jQuery'], init: function ($) { 

    //do whatever with $.widget , all reference of 
    // jQuery-ui is accessible here, override 


return this; //very imp , so all your module will use your 
       // modified jQuery-UI reference 

} }, 
0

я столкнулся с аналогичными, очень случайными ошибками при использовании JQuery UI с Require.js, что я неподвижный с помощью сценария jqueryui-amd преобразования для создания «AMD-обернутых модулей для Jquery UI для использования в таких загрузчиках, как RequireJS ".

  1. Установить с использованием npm.

    npm install -g jqueryui-amd 
    
  2. Преобразование файлов Jquery UI JavaScript, как загрузить с jqueryui.com

    jqueryui-amd path/to/jquery-ui-version 
    
  3. Затем добавьте путь к новой директории преобразованный jqueryui вашим require.js конфигурационный файл.

    requirejs.config({ 
        paths: { 
         jqueryui: 'path/to/jquery-ui-version/jqueryui' 
        } 
    }); 
    
  4. Наконец, в файле JavaScript, где вы используете один из компонентов JQuery UI.

    define(['jquery', 'jqueryui/widget', 'jqueryui/button'], function ($) { 
        //Use widget and button in here, off of the given $ variable. 
    }); 
    
0

У меня была такая же проблема, как вы, определяя свои виджеты внутри модулей RequireJS, и даже если я не 100% уверен, что это лучшее решение, это один, который работал на меня, не нарушая целостность модулей:

requirejs.config({ 
    //By default load any module IDs from js/lib 
     baseUrl: 'js', 
     shim: { 
      'jquery': { 
       exports: 'jQuery' 
      }, 
      'jquery-ui': { 
       deps: ['jquery'], 
       exports: '$' 
      } 
     } 
    }); 

Когда вам требуется JQuery-UI в вашем модуле, JQuery будет автоматически требуется, и $ объект будет иметь все, что вам нужно.

Смежные вопросы