2014-01-28 2 views
3

Я пытаюсь запустить приложение, использующее как AngularJS, так и RequireJS. У меня возникают проблемы с тем, что моя библиотека OpenLayers работает в этой настройке.Использование OpenLayers с RequireJS и AngularJS

Я установил основные AMD-модули в main.js:

require.config(
    { 
     baseUrl: 'scripts', 
     paths: { 
      // Vendor modules 
      angular: 'vendor/angular/angular', 
      openLayers: 'vendor/openlayers-debug', 
      other modules..... 
     }, 
     shim: { 
      angular: { 
       exports: 'angular' 
      }, 
      openLayers: { 
       exports: 'OpenLayers' 
      }, 
      other modules.... 
     } 
    } 
); 

require(['openLayers', 
     'angular', 
     'app', 
     'controllers/olMapController', 
     'directives/olMap', 
     other modules... 
    ], function(OpenLayers) { 
     return OpenLayers; 
    } 
); 

Затем в угловом контроллер я использую для инициализации OpenLayers, я стараюсь, чтобы указать, что OpenLayers-debug.js является зависимость :

define(['openLayers'], 
    function(OpenLayers) { 
     controllers.controller('olMapController', ['$scope', function(scope) { 
      console.log('Loaded olMapController. OpenLayers version: ' + OpenLayers.VERSION_NUMBER); 
     }]); 
    } 
); 

Ну, это не работает. ИНОГДА выполняется функция olMapController, но в основном нет. Консоль затем просто выводит сообщение об ошибке с указанием:

Error: [ng:areq] Argument 'olMapController' is not a function, got undefined

Так что, я думаю, OpenLayers не закончил загрузку еще, но почему-то требуют думает, что имеет, и продолжает загрузку кода, который зависит от OpenLayers, в этом случае olMapController. Затем он не может найти свою зависимость, после чего Angular возвращает это сообщение об ошибке. Или что-то типа того...? Иногда случается что-то, что заставляет OpenLayers загружаться достаточно быстро, чтобы он присутствовал, когда он загружается как зависимость. Что это, я не могу сказать.

Я забыл, что другие библиотеки и модули требуют и определяют, чтобы код читался. Надеюсь, что этот пример по-прежнему понятен.

Любые идеи о том, что я мог бы сделать, чтобы заставить openlayers хорошо загружаться? Сообщение об ошибке исчезает, когда я покидаю зависимость ['openLayers'] от olMapController.

Заранее благодарим за любую помощь.

С наилучшими пожеланиями, Мартейн Senden

+0

ошибка, что вы показываете не предполагает, что OpenLayers еще не загружен. Это предполагает, что любой код пытается использовать 'olMapController' пытается использовать его до его определения. Может быть, какой-то код в '' директивах/olMap''? – Louis

+0

Контроллер в примере кода, который я дал, требует только OpenLayers. В моем реальном приложении это требует большего. Когда я удаляю из него зависимость OpenLayers, ошибка исчезает. Вот почему я думаю, что OpenLayers еще не загружен. Директива olMap не слишком много. Он создает новую карту OpenLayers, используя класс, определенный в контроллере. – Martijn

ответ

3

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

Я бы предложил написать директиву, которая использует head.js для загрузки необходимых вам библиотек в определенный контекст. Можно также подумать о директиве, которая инициализирует openLayers таким образом.

Я полагаю, что ваша ошибка связана с синхронизацией, потому что загрузка модуля и angular.js не синхронизирована - точнее, между ними не существует никакой синхронизации.

обновление
Чтобы повторить мой комментарий, который, наконец, помогли привести ОП в правильном направлении:

Вы должны решить, какие рамки дает тон. Если вы идете с requireJS, тогда требуйте все и бутстрап вручную. (Удалите ng-app = "" из index.html) и выполните `angular.bootstrap() ', когда requirejs завершится. Поэтому, скорее всего, проблема заключается в том, что угловые начинают слишком рано.

+0

Проблема с синхронизацией - это точно. Я действительно хочу, чтобы модули AMD требовали JS. Я думаю, что head.js не поможет мне. У меня угловая и требует совместной работы, она просто не работает на этом контроллере с зависимостью OpenLayers. – Martijn

+1

Это была точка ответа. Вы должны решить, какая структура дает тон. Если вы идете с requireJS, тогда требуйте все и бутстрап вручную. (Удалите 'ng-app =" "из index.html) и выполните' angular.bootstrap() ', когда requirejs завершится. Поэтому, скорее всего, проблема заключается в том, что угловые начинают слишком рано. – angabriel

+0

Хорошая точка. У меня уже есть функция domReady (http://requirejs.org/docs/api.html#pageload), которая ждет, когда dom загрузится, прежде чем Angular загрузится, поэтому я не использую ng-app. Однако, возможно, дом готов, но этого не требуется. Как я могу проверить, завершено ли требование, загрузив все? – Martijn

5

Ну, только для справки мое окончательное решение. comment от angabriel поставил меня в правильном направлении.

Like i said, Я использую domReady module от RequireJS до бутстрапа. Угловая. Это все еще вызвано к началу, потому что OpenLayers еще не загружен при начале углов.RequireJS также предоставляет свойство обратного вызова в require.config. Это функция, которая запускается при загрузке всех зависимостей. Поэтому я использовал эту функцию, чтобы потребовать модуль угловой бутстрапа. Моя конфигурация теперь выглядит следующим образом:

require.config(
    { 
     baseUrl: 'scripts', 
     paths: { 
      // Vendor modules 
      angular: 'vendor/angular/angular', 
      domReady: 'vendor/domReady', 
      openLayers: 'vendor/openlayers-debug', 
      etcetera.... 

     }, 
     shim: { 
      angular: { 
       deps: ['jquery'], 
       exports: 'angular' 
      }, 
      openLayers: { 
       exports: 'OpenLayers' 
      }, 
     }, 
     deps: ['angular', 
      'openLayers', 
      'app', 
      'domReady', 
      'controllers/rootController', 
      'controllers/olMapController', 
      'directives/olMap' 
     ], 
     callback: function() { 
      require(['bootstrap']); 
     } 
    } 
); 

И бутстраповская модуль выглядит следующим образом:

define(['angular', 'domReady', 'app'], function(angular, domReady) { 
    domReady(function() { 
     angular.bootstrap(document, ['GRVP']); 
    }); 
}); 

Спасибо за помощь. @angabriel: Я одобрил ваш комментарий. Невозможно принять комментарий в качестве ответа, не так ли? Ваш первоначальный ответ не был на самом деле ответ на мой вопрос, но комментарий помогло ...

С уважением, Martijn

+1

Спасибо, большое вам отправил ваше решение. Я добавил этот полезный комментарий к моему ответу, чтобы вы могли его поддержать;). – angabriel

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