Подтвердить что ты не робот

AngularJS: Как вложить приложения в приложение angular

Я работал над проектом, который больше похож на структуру, и имеет несколько приложений/модулей, которые вы можете установить. Смотрите это как базовое хранилище appstore или google.play. Это своего рода приложение для интрасети, и все модули могут быть добавлены в ваш пользовательский счет.

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

приложение должно быть несколько автономным и не в состоянии внезапно включать скрипты из фреймворка. Это вполне возможно, структурируя их в отдельных модулях:

angular.module('myApp', []);

однако приложение может иметь шаблоны, скрипты, css и может работать на отдельном сервере, поэтому я ищу наилучший способ получить script (s) и cssfile и динамически загрузите их в приложение, когда пользователь запустит app изнутри рамки.

  • В настоящее время я структурирую приложения, как если бы они имели основной шаблон, например www.framework.com/apps/myapp/views/app.html, для простоты я собирал скрипты в 1 файл script для каждого приложения, поэтому есть также www.framework.com/apps/myapp/script.js.

Структура содержит шаблон, который загружает приложения, и appController. Шаблон содержит этот фрагмент:

<div data-ng-controller="AppController" data-ng-include="app.appTemplate">
    <div>loading...</div>
</div>

это в основном связывается с $scope.app.appTemplate, который обновляется при загрузке всех скриптов, поэтому сначала он показывает шаблон загрузки, позже после включения сценариев на страницу он обновляет app.appTemplate до вышеупомянутого основного шаблона приложение.

при загрузке первого шаблона индекса работает, этот шаблон в настоящее время загружается с помощью appController из фреймворка, поэтому он использует $scope фреймворка, а не собственный script.

Мне еще нужно как-то запустить собственный модуль angular приложения и позволить ему самостоятельно, без чего-либо в рамках, чтобы "заставить его работать"

Я все еще выясняю, как лучше всего загружать зависимые файлы javascript (вероятно, будет использовать requrejs или другой загрузчик зависимостей), но в настоящее время я не знаю, как "загружать" приложение, не работая в рамках appController

ИЗМЕНИТЬ

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

4b9b3361

Ответ 1

Вы не можете загружать модуль внутри другого загрузочного модуля. Bootstrapping компилирует представление и связывает с ним rootScope, пересекая его через DOM и настраивая привязки к областям и выполняя функции привязки директив до конца. Если вы сделаете это дважды, вы столкнетесь с проблемами.

Вероятно, вам придется переосмыслить свою архитектуру. Я думаю, что слово "модуль" или "приложение", поскольку оно относится к Angular, является неправильным и ведет вас по неправильному пути.

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

Что бы вы сделали, когда был установлен новый "виджет", вы зарегистрируете его в файле модуля (.js) с системой, которая будет содержать контроллер с именем WidgetCtrl, а затем, когда ваша страница будет загружена, вы обратитесь к модулю виджетов вашего модуля приложения. Оттуда он должен быть доступен для динамического назначения элементам с помощью ng-controller и/или ng-include.

Надеюсь, это имеет смысл.

Ответ 2

В отличие от принятого в настоящее время ответа, это действительно возможно.

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

  • Сообщите основному приложению игнорировать дочерний элемент.
  • Загрузите дочерний элемент.

Существует атрибут ng-non-bindable, который просто указывает AngularJS игнорировать элемент. Это устраняет нашу первую проблему.

Однако при попытке инициализировать дочерний элемент; AngularJS выдает ошибку, сообщая вам, что она уже загружена (по крайней мере, мне, версия 1.2.13). Следующий трюк делает работу:

<div ng-non-bindable data-$injector="">
  <div id="bootstrap-me">
    <script src="/path/to/app.js"></script>
    <div ng-include="'/path/to/app.html'"/>
  </div>
</div>

Это решение не идеально. В идеале, атрибут ng-non-bindable может добавить к элементу атрибут data - $injector. Я собираюсь сделать функцию и, надеюсь, получить запрос на AngularJS.


У меня не было возможности сделать запрос на тяну. Очевидно, и я должен сказать, что некоторые внутренние изменения изменились, но ng-non-bindable все еще работает в версии 1.3.13 с использованием демо-кода Ventzy Kunev (еще раз спасибо, см. Ссылку ниже).

Ответ 3

хорошо, если каждое вспомогательное приложение находится в своем собственном модуле, вы можете просто использовать angular.bootstrap для динамического загрузки этого модуля. когда URL-адрес для конкретного приложения загружается, вы можете получить необходимые script (s), а затем, когда обещание будет разрешено, вы можете сделать что-то по строкам:

// grab a reference to the element where you'll be loading the sub-app
var subapp = document.getElementById('subapp-id');

// assuming the script you get back contains an angular module declaration named
// 'subapp', manually start the sub-app
angular.bootstrap(angular.element(subapp), ['subapp']);

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

Ответ 4

Как и в случае с UnicodeSnowman, выше, другое потенциальное решение, которое, кажется, работает для моих нужд (я построил живой редактор Angular на сайте документации), должен вручную обработать процесс начальной загрузки, имея <div id="demos">, который является отдельным от основного <div id="myApp">.

Эта статья была очень полезной для правильной работы.

Общий процесс

  • Создайте основное приложение (я выбрал ручную загрузку, но вы можете использовать ng-app для этой части)
  • Создайте новую структуру HTML/приложение (в моем случае демонстрационное приложение):
  • Добавьте его в div demos с пользовательским идентификатором: someCoolDemoContainer
  • Boostrap вновь созданного приложения
  • Переместите его обратно в исходное приложение (для размещения/размещения)

Пример кода (не проверен, просто показывает базовый процесс)

<div id="myApp">
    <h1>Demo</h1>

    <p>Click the button below to checkout the cool demo!</p>

    <button ng-click="showDemo()">Show Demo</button>

    <div class='insertion-point'></div>
</div>

<div id="demos">
</div>

<script type="text/javascript">
    /*
     * Init/bootstrap our main app
     */
    var appContainer = document.getElementById('myApp');

    angular.module('myApp', ['myDependency']);
    angular.bootstrap(appContainer, ['myApp']);

    // Do lots of other things like adding controllers/models/etc.

    /*
     * Init/bootstrap our demo app when the user clicks a button
     */
    function showDemo() {
      // Append our demo code
      $('#demos').append('<div id="someCoolDemoContainer">Angular app code goes here</div>');

      // Bootstrap the new app
      var demoContainer = document.getElementById('someCoolDemoContainer');
      angular.module('someCoolDemo', ['myDependency']);
      angular.module('someCoolDemo').controller('myController', function() { ... });

      angular.bootstrap(demoContainer, ['someCoolDemo']);

      // Re-insert it back into the DOM where you want it
      $('#myApp').find('.insertion-point').append($('#someCoolDemoContainer'));
    }
</script>

Ответ 5

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

Я нашел два способа сделать это, оба использовали ручную загрузку приложения angularjs в ngOnInit компонента Angular:

ngOnInit(): void {
  // manually bootstrap the angularjs app
  angular.bootstrap(document.getElementById('ngListApp'), ['list-app']);
}

Либо установите атрибут ngNonBindable для элемента, который будет загружен:

<div ngNonBindable #insert>
  <!-- can insert the angular js template directly here, inside non-bindable element -->
  <div id="ngListApp" ng-controller="ListController as list">
    <input ng-model="inputValue" />
    <ul>
      <li ng-repeat="item in items">{{ item }}</li>
    </ul>
  </div>
</div>

Или вставьте html-шаблон angularjs в элемент в обработчике событий ngOnInit в компоненте Angular, чтобы Angular не пытался интерпретировать код AngularJS (особенно интерполяцию свойств AngularJS в DOM с помощью фигурных скобок) во время компиляции.

ngOnInit(): void{
  // insert angularjs template html here
  this.div.nativeElement.innerHTML = this.htmlTemplate;

  // then manually bootstrap the angularjs app
  angular.bootstrap(document.getElementById('ngListApp'), ['list-app']);
}

Plunker здесь:

http://plnkr.co/plunks/0qOJ6T8roKQyaSKI