Я использую AngularJS для создания элементов управления HTML, которые взаимодействуют с устаревшим приложением Flex. Все обратные вызовы из приложения Flex должны быть прикреплены к окну DOM.
Например (в AS3)
ExternalInterface.call("save", data);
Позвоню
window.save = function(data){
// want to update a service
// or dispatch an event here...
}
Из функции изменения размера JS я бы хотел отправить событие, которое может услышать контроллер. Кажется, что создание сервиса - это путь. Можете ли вы обновить сервис за пределами AngularJS? Может ли контроллер прослушивать события из службы? В одном эксперименте (нажмите на скрипку) я сделал, кажется, что я могу получить доступ к сервису, но обновление данных сервиса не отражается в представлении (в примере <option>
следует добавить к <select>
).
Спасибо!
var injector = angular.injector(['ng', 'MyApp']);
. Это даст вам совершенно новый контекст и дубликатmyService
. Это означает, что вы получите два экземпляра сервиса и модели и будете добавлять данные в неправильное место. Вместо этого вы должны использовать целевой элемент в приложении, используяangular.element('#ng-app').injector(['ng', 'MyApp'])
. На этом этапе вы можете использовать $ apply для переноса изменений модели.Ответы:
Взаимодействие от внешнего к угловому аналогично отладке углового приложения или интеграции со сторонней библиотекой.
Для любого элемента DOM вы можете сделать это:
angular.element(domElement).scope()
чтобы получить текущую область видимости для элементаangular.element(domElement).injector()
чтобы получить текущий инжектор приложенияangular.element(domElement).controller()
овладетьng-controller
экземпляр.С инжектора вы можете получить любой сервис в угловом приложении. Аналогичным образом из области вы можете вызывать любые методы, которые были опубликованы в ней.
Имейте в виду, что любые изменения в угловой модели или любые вызовы методов в области должны быть обернуты
$apply()
следующим образом:источник
[ng-app]
корневого узла кажется обратной, когда у меня уже есть ссылка на Модуль ...angular.element(document.getElementById(divName)).scope()
, но я не могу вызвать какие-либо функции из него, он просто возвращает "undefined" в консоли.Миско дал правильный ответ (очевидно), но некоторые из нас, новичков, могут нуждаться в его упрощении в дальнейшем.
Когда речь идет о вызове кода AngularJS из устаревших приложений, думайте о коде AngularJS как о «микро-приложении», существующем в защищенном контейнере в вашем устаревшем приложении. Вы не можете делать вызовы напрямую (по очень веской причине), но вы можете делать удаленные вызовы с помощью объекта $ scope.
Чтобы использовать объект $ scope, вам нужно получить дескриптор $ scope. К счастью, это очень легко сделать.
Вы можете использовать идентификатор любого HTML-элемента в HTML-приложении AngularJS, чтобы получить дескриптор области приложения AngularJS.
В качестве примера, скажем, мы хотим вызвать несколько функций в нашем контроллере AngularJS, таких как sayHi () и sayBye (). В AngularJS HTML (просмотр) у нас есть div с идентификатором «MySuperAwesomeApp». Вы можете использовать следующий код в сочетании с jQuery, чтобы получить дескриптор $ scope:
Теперь вы можете вызывать функции кода AngularJS с помощью дескриптора области:
Чтобы сделать вещи более удобными, вы можете использовать функцию для захвата дескриптора области в любое время, когда вы захотите получить к нему доступ:
Тогда ваши звонки будут выглядеть так:
Вы можете увидеть рабочий пример здесь:
http://jsfiddle.net/peterdrinnan/2nPnB/16/
Я также показал это в слайд-шоу для группы Ottawa AngularJS (просто перейдите к последним 2 слайдам)
http://www.slideshare.net/peterdrinnan/angular-for-legacyapps
источник
<input type="button" onclick="angular.element(this).scope().edit.delete();" value="delete">
Величайшее объяснение концепции, которую я нашел, находится здесь: https://groups.google.com/forum/#!msg/angular/kqFrwiysgpA/eB9mNbQzcHwJ
Чтобы сохранить вас нажав:
источник
id
в верхний элемент HTML, а затем сделатьdocument.getElementById()
этот идентификатор. Это дает вам доступ к области действия этого контроллера. методы / свойства и т. д. просто добавьте тонкости в комментарии гусеманджека.В дополнение к другим ответам. Если вы не хотите обращаться к методу в контроллере, но хотите получить прямой доступ к сервису, вы можете сделать что-то вроде этого:
источник
Благодаря предыдущему посту я могу обновить свою модель с помощью асинхронного события.
Я объявляю свою модель
И я обновляю свою модель вне моей области
источник
Более безопасный и эффективный способ, особенно когда отладочные данные отключены, - это использование общей переменной для хранения функции обратного вызова. Ваш угловой контроллер реализует эту функцию, чтобы вернуть свои внутренние данные внешнему коду.
Обобщается как директива многократного использования:
Я создал директиву exposeScope, которая работает аналогичным образом, но ее использование проще:
Это сохраняет текущую область (которая дается функции связи директивы) в глобальном объекте «области видимости», который является держателем для всех областей. Значение, предоставленное атрибуту директивы, используется в качестве имени свойства области в этом глобальном объекте.
Смотрите демо здесь . Как я показал в демонстрации, вы можете запускать события jQuery, когда область сохраняется и удаляется из глобального объекта «области видимости».
Обратите внимание, что я не тестировал on ('scopeDestroyed'), когда фактический элемент удаляется из DOM. Если это не работает, может помочь запуск события на самом документе вместо элемента. (см. app.js) скрипт в демонстрационном плунжере.
источник
Я знаю, что это старый вопрос, но я недавно искал варианты сделать это, поэтому я решил поместить свои выводы здесь на тот случай, если они кому-нибудь пригодятся.
В большинстве случаев, если существует потребность во внешнем унаследованном коде для взаимодействия с состоянием пользовательского интерфейса или внутренней работой приложения, служба может быть полезна для отвлечения этих изменений. Если внешний код взаимодействует напрямую с вашим угловым контроллером, компонентом или директивой, вы сильно связываете свое приложение с унаследованным кодом, что является плохой новостью.
В моем случае я использовал комбинацию глобальных переменных, доступных в браузере (например, окна) и обработки событий. Мой код имеет интеллектуальный механизм генерации форм, который требует вывода JSON из CMS для инициализации форм. Вот что я сделал:
Форма службы формы создается с использованием углового инжектора, как и ожидалось:
И в моих контроллерах: function () {'use strict';
Пока что это чисто угловое и JavaScript-сервис-ориентированное программирование. Но унаследованная интеграция приходит сюда:
Очевидно, что у каждого подхода есть свои достоинства и недостатки. Преимущества и использование этого подхода зависят от вашего пользовательского интерфейса. Предложенные ранее подходы не работают в моем случае, так как моя схема формы и унаследованный код не контролируют и не знают угловых областей. Следовательно, настройка моего приложения на основе
angular.element('element-X').scope();
может потенциально сломать приложение, если мы изменим границы. Но если ваше приложение знает об объеме и может полагаться на то, что оно не меняется часто, то, что было предложено ранее, является жизнеспособным подходом.Надеюсь это поможет. Любые отзывы также приветствуются.
источник