콜 앵귤러레거시 코드의 JS
Angular를 사용하고 있습니다.JS는 레거시 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>
를 참조해 주세요.
감사합니다!
angular 외부에서 angular로의 interop은 angular 어플리케이션을 디버깅하거나 서드파티 라이브러리와 통합하는 것과 동일합니다.
임의의 DOM 요소에 대해서, 다음의 조작을 실시할 수 있습니다.
angular.element(domElement).scope()
.angular.element(domElement).injector()
injector를angular.element(domElement).controller()
을ng-controller
★★★★★★ 。
인젝터에서 각도 적용 시 모든 서비스를 받을 수 있습니다.마찬가지로 범위에 게시된 메서드를 호출할 수 있습니다.
in in in in in in in음음 、 음음음음음음음 keep 。$apply()
음음음같 뭇매하다
$scope.$apply(function(){
// perform any model changes or method invocations here on angular app.
});
Misko는 (분명히) 정답을 제시했지만, 우리 신입사원들 중 일부는 그것을 더 단순화해야 할지도 모릅니다.
Angular를 호출하는 경우기존 앱의 JS 코드를 예로 들 수 있습니다.레거시 응용 프로그램의 보호된 컨테이너 내에 존재하는 "마이크로 앱"인 JS 코드입니다.(매우 타당한 이유로) 직접 콜을 발신할 수는 없지만 $scope 개체를 사용하여 원격 콜을 발신할 수 있습니다.
$scope 객체를 사용하려면 $scope의 핸들을 잡아야 합니다.다행히도 이것은 매우 쉽다.
AngularJS "micro-app" HTML 내의 임의의 HTML 요소의 ID를 사용하여 Angular의 핸들을 얻을 수 있습니다.JS 앱 $scope.
예를 들어, Angular에서 몇 가지 함수를 호출한다고 가정해 보겠습니다.sayHi() 및 sayBye() 등의 JS 컨트롤러.AngularJS HTML(뷰)에는 "My Super Awesome App"이라는 ID가 있는 div가 있습니다.다음 코드를 jQuery와 조합하여 $scope의 핸들을 얻을 수 있습니다.
var microappscope = angular.element($("#MySuperAwesomeApp")).scope();
이제 Angular를 호출할 수 있습니다.JS 코드는 스코프 핸들을 통해 작동합니다.
// 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/
오타와 앵귤러에 대한 슬라이드 쇼에서도 보여줬습니다.JS 그룹(마지막 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' 개체에 저장됩니다.디렉티브 Atribute에 제공된 값은 이 글로벌오브젝트에서 스코프의 속성명으로 사용됩니다.
데모를 보려면 여기를 클릭하십시오.데모에서 보여드린 것처럼 스코프가 저장되고 글로벌 '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 ])
컨트롤러에서는 기능() {use strict};
angular.module('myApp').controller('MyController', MyController);
MyEncapsulatorController.$inject = ['$scope', 'FormSchemaService'];
function MyController($scope, formSchemaService) {
// using the already configured formSchemaService
formSchemaService.buildForm();
지금까지 이것은 순수한 각도 및 Javascript 서비스 지향 프로그래밍입니다.그러나 레거시 통합은 다음과 같습니다.
<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();
범위를 바꾸면 앱이 망가질 수 있습니다.그러나 앱이 범위 지정에 대한 지식이 있고 자주 변경되지 않는 앱에 의존할 수 있다면 이전에 제안했던 방법이 실행 가능한 방법입니다.
이게 도움이 됐으면 좋겠다.어떤 피드백도 환영합니다.
언급URL : https://stackoverflow.com/questions/10490570/call-angularjs-from-legacy-code
'programing' 카테고리의 다른 글
Wordpress의 게시 상자에 있는 게시물 편집 페이지에 필드를 추가하려면 어떻게 해야 합니까? (0) | 2023.03.11 |
---|---|
리액트 리덕스 및 웹 소켓(소켓 포함)이오 (0) | 2023.03.11 |
NSURLSession에서 Swift를 사용하여 쿠키를 가져오려면 어떻게 해야 합니까? (0) | 2023.03.11 |
Redux를 사용하여 connect를 사용하여 이 . props에서 간단한 디스패치를 얻는 방법 (0) | 2023.03.11 |
nginx에서 JSON 로그를 생성하는 방법 (0) | 2023.03.11 |