programing

콜 앵귤러레거시 코드의 JS

showcode 2023. 3. 11. 09:41
반응형

콜 앵귤러레거시 코드의 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

반응형