AngularJS를 사용하여 레거시 Flex 응용 프로그램과 상호 작용하는 HTML 컨트롤을 작성하고 있습니다. 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>
).
감사!
답변
각도 외부에서 각도로의 Interop은 각도 응용 프로그램을 디버깅하거나 타사 라이브러리와 통합하는 것과 같습니다.
모든 DOM 요소에 대해 다음을 수행 할 수 있습니다.
angular.element(domElement).scope()
요소의 현재 범위를 가져옵니다.angular.element(domElement).injector()
현재 앱 인젝터를 얻으려면angular.element(domElement).controller()
ng-controller
인스턴스 를 확보 합니다.
인젝터에서 각도 어플리케이션의 모든 서비스를 유지할 수 있습니다. 마찬가지로 범위에서 게시 된 모든 메서드를 호출 할 수 있습니다.
각도 모델에 대한 변경 사항이나 범위에서 메서드 호출은 다음 $apply()
과 같이 래핑해야합니다 .
$scope.$apply(function(){
// perform any model changes or method invocations here on angular app.
});
답변
Misko가 정답을 줬지만, 우리 중 일부는 더 단순화해야 할 수도 있습니다.
레거시 앱 내에서 AngularJS 코드를 호출 할 때는 AngularJS 코드를 레거시 애플리케이션의 보호 된 컨테이너 내에 존재하는 “마이크로 앱”이라고 생각하십시오. 직접 호출 할 수는 없지만 (정당한 이유로) $ scope 객체를 통해 원격 호출을 할 수 있습니다.
$ scope 객체를 사용하려면 $ scope 핸들을 가져와야합니다. 다행히도 이것은 매우 쉽습니다.
AngularJS “micro-app”HTML에서 HTML 요소의 id를 사용하여 AngularJS 앱 $ scope의 핸들을 얻을 수 있습니다.
예를 들어 AngularJS 컨트롤러 내에서 sayHi () 및 sayBye ()와 같은 몇 가지 함수를 호출하려고한다고 가정합니다. AngularJS HTML (보기)에는 ID가 “MySuperAwesomeApp”인 div가 있습니다. 다음 코드를 jQuery와 결합하여 $ scope의 핸들을 얻을 수 있습니다.
var microappscope = angular.element($("#MySuperAwesomeApp")).scope();
이제 범위 핸들을 통해 AngularJS 코드 함수를 호출 할 수 있습니다.
// we are in legacy code land here...
microappscope.sayHi();
microappscope.sayBye();
보다 편리한 작업을 위해 함수를 사용하여 액세스하려는 경우 언제든지 범위 핸들을 잡을 수 있습니다.
function microappscope(){
return angular.element($("#MySuperAwesomeApp")).scope();
}
그러면 귀하의 전화는 다음과 같습니다 :
microappscope().sayHi();
microappscope().sayBye();
여기에 실제 예제가 있습니다.
http://jsfiddle.net/peterdrinnan/2nPnB/16/
또한 Ottawa AngularJS 그룹의 슬라이드 쇼에서 이것을 보여주었습니다 (마지막 2 슬라이드로 건너 뛰십시오)
http://www.slideshare.net/peterdrinnan/angular-for-legacyapps
답변
내가 찾은 개념에 대한 가장 큰 설명은 https://groups.google.com/forum/#!msg/angular/kqFrwiysgpA/eB9mNbQzcHwJ 에 있습니다.
클릭을 저장하려면 다음을 수행하십시오.
// get Angular scope from the known DOM element
e = document.getElementById('myAngularApp');
scope = angular.element(e).scope();
// update the model with a wrap in $apply(fn) which will refresh the view for us
scope.$apply(function() {
scope.controllerMethod(val);
});
답변
다른 답변에 더. 컨트롤러의 메소드에 액세스하지 않고 서비스에 직접 액세스하려는 경우 다음과 같이 할 수 있습니다.
// Angular code* :
var myService = function(){
this.my_number = 9;
}
angular.module('myApp').service('myService', myService);
// External Legacy Code:
var external_access_to_my_service = angular.element('body').injector().get('myService');
var my_number = external_access_to_my_service.my_number
답변
이전 게시물 덕분에 비동기 이벤트로 모델을 업데이트 할 수 있습니다.
<div id="control-panel" ng-controller="Filters">
<ul>
<li ng-repeat="filter in filters">
<button type="submit" value="" class="filter_btn">{{filter.name}}</button>
</li>
</ul>
</div>
내 모델을 선언합니다
function Filters($scope) {
$scope.filters = [];
}
그리고 내 범위 밖에서 모델을 업데이트합니다.
ws.onmessage = function (evt) {
dictt = JSON.parse(evt.data);
angular.element(document.getElementById('control-panel')).scope().$apply(function(scope){
scope.filters = dictt.filters;
});
};
답변
특히 디버그 데이터가 꺼져있을 때 더 안전하고 성능이 좋은 방법은 공유 변수를 사용하여 콜백 함수를 유지하는 것입니다. 각도 컨트롤러는이 함수를 구현하여 내부 코드를 외부 코드로 반환합니다.
var sharedVar = {}
myModule.constant('mySharedVar', sharedVar)
mymodule.controller('MyCtrl', [ '$scope','mySharedVar', function( $scope, mySharedVar) {
var scopeToReturn = $scope;
$scope.$on('$destroy', function() {
scopeToReturn = null;
});
mySharedVar.accessScope = function() {
return scopeToReturn;
}
}]);
재사용 가능한 지시어로 일반화되었습니다.
비슷한 방식으로 작동하는 ‘exposeScope’지시문을 만들었지 만 사용법이 더 간단합니다.
<div ng-controller="myController" expose-scope="aVariableNameForThisScope">
<span expose-scope='anotherVariableNameForTheSameScope" />
</div>
이것은 현재 범위 (지시문의 링크 함수에 제공됨)를 모든 범위의 홀더 인 전역 ‘scopes’객체에 저장합니다. 지시문 속성에 제공된 값은이 전역 객체에서 범위의 속성 이름으로 사용됩니다.
여기 데모를 참조 하십시오 . 데모에서 알 수 있듯이 범위가 전역 ‘scopes’객체에서 저장되고 제거되면 jQuery 이벤트를 트리거 할 수 있습니다.
<script type="text/javascript" >
$('div').on('scopeLinked', function(e, scopeName, scope, allScopes) {
// access the scope variable or the given name or the global scopes object
}.on('scopeDestroyed', function(e, scopeName, scope, allScopes) {
// access the scope variable or the given name or the global scopes object
}
</script>
실제 요소가 DOM에서 제거 될 때 on ( ‘scopeDestroyed’)을 테스트하지 않았습니다. 작동하지 않으면 요소 대신 문서 자체에서 이벤트를 트리거하는 것이 도움이 될 수 있습니다. 데모 플 런커의 (app.js 참조) 스크립트
답변
나는 이것이 오래된 질문이라는 것을 알고 있지만 최근에 이것을 할 수있는 옵션을 찾고 있었으므로 누군가에게 도움이 될 수 있도록 여기에 찾은 것을 여기에 넣었다고 생각했습니다.
대부분의 경우 외부 레거시 코드가 UI 상태 또는 응용 프로그램의 내부 작업과 상호 작용해야하는 경우 이러한 변경 사항을 추상화하는 데 서비스가 유용 할 수 있습니다. 외부 코드가 각도 컨트롤러, 구성 요소 또는 지시문과 직접 상호 작용하는 경우 나쁜 소식 인 레거시 코드와 앱이 크게 결합됩니다.
필자의 경우에 사용했던 것은 브라우저 액세스 가능한 전역 (예 : window)과 이벤트 처리의 조합입니다. 내 코드에는 스마트 양식 생성 엔진이있어 양식을 초기화하기 위해 CMS의 JSON 출력이 필요합니다. 내가 한 일은 다음과 같습니다.
function FormSchemaService(DOM) {
var conf = DOM.conf;
// This event is the point of integration from Legacy Code
DOM.addEventListener('register-schema', function (e) {
registerSchema(DOM.conf);
}, false);
// service logic continues ....
양식 스키마 서비스는 예상대로 각도 인젝터를 사용하여 작성됩니다.
angular.module('myApp.services').
service('FormSchemaService', ['$window' , FormSchemaService ])
그리고 내 컨트롤러에서 : function () { ‘use strict’;
angular.module('myApp').controller('MyController', MyController);
MyEncapsulatorController.$inject = ['$scope', 'FormSchemaService'];
function MyController($scope, formSchemaService) {
// using the already configured formSchemaService
formSchemaService.buildForm();
지금까지 이것은 순수한 각도 및 자바 스크립트 서비스 지향 프로그래밍입니다. 그러나 레거시 통합은 다음과 같습니다.
<script type="text/javascript">
(function(app){
var conf = app.conf = {
'fields': {
'field1: { // field configuration }
}
} ;
app.dispatchEvent(new Event('register-schema'));
})(window);
</script>
분명히 모든 접근 방식에는 장점과 단점이 있습니다. 이 방법의 장점과 사용은 UI에 따라 다릅니다. 내 양식 스키마와 레거시 코드에는 각도 범위에 대한 제어 및 지식이 없으므로 이전에 제안 된 방법은 작동하지 않습니다. 따라서 angular.element('element-X').scope();
범위를 변경하면 앱을 기반으로 구성 하면 앱이 중단 될 수 있습니다. 그러나 응용 프로그램이 범위 지정에 대한 지식을 가지고 있으며 자주 변경되지 않는 응용 프로그램에 의존 할 수 있다면 이전에 제안 된 것은 실행 가능한 접근법입니다.
도움이 되었기를 바랍니다. 모든 의견도 환영합니다.
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)