লিগ্যাসি কোড থেকে অ্যাঙ্গুলারজেএস কল করুন


180

আমি লিগ্যাসি ফ্লেক্স অ্যাপ্লিকেশনের সাথে ইন্টারেক্ট করে এমন এইচটিএমএল নিয়ন্ত্রণগুলি তৈরি করতে AngularJS ব্যবহার করছি। ফ্লেক্স অ্যাপ্লিকেশন থেকে সমস্ত কলব্যাকগুলি অবশ্যই ডিওএম উইন্ডোতে সংযুক্ত থাকতে হবে।

উদাহরণস্বরূপ (এএস 3 এ)

ExternalInterface.call("save", data);

ডাকবে

window.save = function(data){
    // want to update a service 
    // or dispatch an event here...
}

জেএস পুনরায় আকার ফাংশনটির মধ্য থেকে আমি এমন একটি ইভেন্ট প্রেরণ করতে চাই যা নিয়ামক শুনতে পাবে। দেখে মনে হচ্ছে কোনও পরিষেবা তৈরি করা উপায়। আপনি AngularJS এর ​​বাইরে থেকে কোনও পরিষেবা আপডেট করতে পারবেন? কোনও নিয়ামক কোনও পরিষেবা থেকে ইভেন্টগুলি শুনতে পারেন? একটি পরীক্ষায় (ঝাঁকুনির জন্য ক্লিক করুন) আমি দেখে মনে হয়েছিল আমি কোনও পরিষেবা অ্যাক্সেস করতে পারি তবে সেবার ডেটা আপডেট করা ভিউতে প্রতিফলিত হয় না (উদাহরণস্বরূপ একটিতে <option>যোগ করা উচিত <select>)।

ধন্যবাদ!


1
দ্রষ্টব্য যে উপরে jsfiddle ইনজেক্টর ব্যবহার করে অ্যাপের মধ্যে কোনও উপাদানকে লক্ষ্য না করেই প্রাপ্ত var injector = angular.injector(['ng', 'MyApp']);। এটি করা আপনাকে সম্পূর্ণ নতুন প্রসঙ্গ এবং একটি সদৃশ দেবে myService। এর অর্থ আপনি পরিষেবা এবং মডেলের দুটি উদাহরণ দিয়ে শেষ করবেন এবং ভুল জায়গায় ডেটা যুক্ত করবেন। পরিবর্তে আপনি অ্যাপ্লিকেশন মধ্যে ব্যবহার করে একটি উপাদান লক্ষ্য করা উচিত angular.element('#ng-app').injector(['ng', 'MyApp'])। এই মুহুর্তে আপনি পরে মডেল পরিবর্তনগুলি মোড়ানো করতে প্রয়োগ করতে পারেন $
থানহ এনগুইন

উত্তর:


293

কৌণিকের বাইরে থেকে কৌণিকের মধ্যে ইন্টারোপ কৌণিক অ্যাপ্লিকেশনটি ডিবাগ করা বা তৃতীয় পক্ষের লাইব্রেরির সাথে সংহত করার সমান।

যে কোনও ডিওএম উপাদানগুলির জন্য আপনি এটি করতে পারেন:

  • 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.
});

1
এটি কাজ করে, তবে আমি চাই যে কোনও মডিউল থেকে সরাসরি তার সুযোগে পৌঁছানোর কোনও উপায় ছিল - এটি কি সম্ভব? একটি সিলেক্ট ফিরে যেতে [ng-app]
পেরে

5
আমি এটি কাজ করতে পারি না: আমি কল করছি angular.element(document.getElementById(divName)).scope(), তবে আমি এটি থেকে কোনও ফাংশন শুরু করতে পারছি না, এটি কেবল কনসোলে "অপরিজ্ঞাত" ফিরিয়ে দেয়।
এমিল

1
এমনকি আমি ইমেলের উপরে বর্ণিত একই সমস্যার মুখোমুখি হয়েছি, এটি অপরিবর্তিত রয়েছে returning কোন সাহায্য ?
বিবিন

5
ডিবাগ ডেটা বন্ধ করা থাকলে উপাদান ()। স্কোপ () কাজ করবে না, যা উত্পাদনের জন্য সুপারিশ। এই পরিস্থিতিতে এটি কি অকেজো করে না? এটি কেবল পরীক্ষার / ডিবাগিংয়ের জন্যই হবে।
কে। নরবার্ট

4
আপনি কৌনিক 1.3 এ এটি করতে চাইবেন না। কৌণিক দল আমাদের উত্পাদন কোডের উপাদানগুলিতে ".স্কোপ ()" কল করার ইচ্ছা করে নি। এটি একটি ডিবাগ সরঞ্জাম হতে বোঝানো হয়েছিল। সুতরাং, কৌনিক 1.3 থেকে শুরু করে, আপনি এটি বন্ধ করতে পারেন। কৌণিক jQuery এর .ডাটা ফাংশনটি ব্যবহার করে উপাদানটির সাথে স্কোপ সংযুক্ত করা বন্ধ করবে। এটি আপনার অ্যাপ্লিকেশনটির গতি বাড়িয়ে তুলবে। অতিরিক্তভাবে, আপনার স্কোপগুলি জ্যাকুরির ক্যাচিং বৈশিষ্ট্যগুলিতে হস্তান্তর করা মেমরি ফাঁস তৈরি করবে। সুতরাং, আপনার অ্যাপ্লিকেশন গতি বাড়ানোর জন্য আপনার অবশ্যই এটি বন্ধ করা উচিত। কৌণিকের সাইটের একটি প্রোডাকশন গাইড রয়েছে যা আপনার আরও শিখতে ব্যবহার করা উচিত।
ফ্রস্টি

86

মিসকো সঠিক উত্তরটি দিয়েছে (স্পষ্টতই), তবে আমাদের মধ্যে কিছু নতুনকে এর আরও সহজতর প্রয়োজন হতে পারে।

যদি লিগ্যাসি অ্যাপ্লিকেশনগুলির মধ্যে থেকে অ্যাংুলারজেএস কোডটি কল করার কথা আসে, তখন আপনার লিগ্র্যাসি আবেদনের সুরক্ষিত ধারকটির মধ্যে থাকা একটি "মাইক্রো অ্যাপ" হিসাবে অ্যাঙ্গুলারজেএস কোডটি ভাবেন। আপনি সরাসরি এটিতে কল করতে পারবেন না (খুব ভাল কারণে) তবে আপনি $ স্কোপ অবজেক্টের মাধ্যমে দূরবর্তী কল করতে পারেন।

$ স্কোপ অবজেক্টটি ব্যবহার করার জন্য আপনার $ স্কোপের হ্যান্ডেলটি পাওয়া দরকার। ভাগ্যক্রমে এটি করা খুব সহজ।

অ্যাঙ্গুলারজেএস অ্যাপ্লিকেশন $ সুযোগের হ্যান্ডেলটি পেতে আপনি আপনার AngularJS "মাইক্রো-অ্যাপ" HTML এর মধ্যে যে কোনও এইচটিএমএল উপাদানের আইডি ব্যবহার করতে পারেন।

উদাহরণ হিসাবে, ধরা যাক আমরা আমাদের অ্যাঙ্গুলারজেএস কন্ট্রোলারের মধ্যে যেমন সিএইহাই () এবং সিউ বাই () এর মধ্যে বেশ কয়েকটি ফাংশন কল করতে চাই। অ্যাঙ্গুলারজেএস এইচটিএমএলতে (দেখুন) "মাইসুপারআউওয়াইজ অ্যাপ" আইডিটি সহ আমাদের একটি ডিভ রয়েছে div $ স্কোপটির হ্যান্ডেলটি পাওয়ার জন্য আপনি jQuery এর সাথে মিলিত নিম্নলিখিত কোডটি ব্যবহার করতে পারেন:

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/

আমি এটি অটোয়া অ্যাঙ্গুলারজেএস গ্রুপের স্লাইডশোতে দেখিয়েছি (কেবল শেষ 2 টি স্লাইডে এড়িয়ে যান)

http://www.slideshare.net/peterdrinnan/angular-for-legacyapps


4
নোট করুন যে কেবলমাত্র লিঙ্ক-উত্তরগুলি নিরুৎসাহিত করা হয়েছে, এসও উত্তরগুলি সমাধানের সন্ধানের শেষ-পয়েন্ট হওয়া উচিত (বনাম। রেফারেন্সগুলির মধ্যে আরও একটি স্টপওভার, যা সময়ের সাথে সাথে বাসি হয়ে যায়)। রেফারেন্স হিসাবে লিঙ্কটি রেখে এখানে দয়া করে এখানে একা একা সংক্ষিপ্তসার বিবেচনা করুন।
ক্লিওপাত্র

চমৎকার অতিরিক্ত ব্যাখ্যা। ধন্যবাদ।
জো

1
সুন্দর ব্যাখ্যা! এটি করে আমাকে একটি ফর্মের বৈধতা <input type="button" onclick="angular.element(this).scope().edit.delete();" value="delete">
আটকানোর

24

আমি যে ধারণাটি পেয়েছি তার সর্বাধিক ব্যাখ্যা এখানে অবস্থিত: 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);
}); 

14
উপরোক্ত কাজ করে যখন অ্যাপ্লিকেশন এবং নিয়ামক একই উপাদানটিতে সহাবস্থান করে। আরও জটিল অ্যাপ্লিকেশনগুলির জন্য যা কোনও টেমপ্লেটের কোনও এনজি-ভিউ নির্দেশিকাটি ব্যবহার করে, আপনাকে অবশ্যই পুরো অ্যাপ্লিকেশনের ডোম উপাদান না দিয়ে ভিউয়ের মধ্যে প্রথম উপাদানটি পেতে হবে। আমাকে একটি ডকুমেন্ট.জেট এলিমেন্টসওয়াই ক্লাসনাম ('এনজি-স্কোপ') দিয়ে উপাদানগুলি ঘিরে ফেলতে হয়েছিল; নোড তালিকা দখল করতে সঠিক স্কোপ DOM উপাদান সনাক্ত করতে।
goosemanjack

আমি জানি এটি একটি সত্যই পুরানো থ্রেড, তবে আমি মনে করি আমি এই সমস্যাটিতে চলে আসছি। কারও কি এমন কোনও কোড রয়েছে যা দেখায় যে ডোম উপাদানটি ধরার জন্য তালিকাটি কীভাবে চলতে হবে?
জেরিকুর

আমার প্রশ্ন উপেক্ষা করুন। আমি স্রেফ ডকুমেন্ট.জেটএলমেন্টবিআইআইডি ('যে কোনও-নিয়ন্ত্রণ-যে-হ্যাস্ট-এনজি-দিকনির্দেশক') স্কোপ () ব্যবহার করে এই কাজটি পেতে সক্ষম হয়েছি।
জেরিকুর

আপনি যদি এনজি-ভিউ ব্যবহার করেন এবং নিজের মতামতগুলি তাদের নিজস্ব ফাইলগুলিতে বিভক্ত করেন। আপনি idউপরের এইচটিএমএল উপাদানটি রাখতে এবং document.getElementById()সেই আইডিটি করতে পারেন। এটি আপনাকে সেই নিয়ামকের সুযোগগুলিতে অ্যাক্সেস দেয়। পদ্ধতি / বৈশিষ্ট্য ইত্যাদি ... গুজম্যানজ্যাকের মন্তব্যে কেবল একটি সূক্ষ্ম বক্তব্য রেখে।
ftravers

13

অন্যান্য উত্তর। আপনি যদি কোনও নিয়ামকের কোনও পদ্ধতিতে অ্যাক্সেস করতে না চান তবে সরাসরি পরিষেবাটি অ্যাক্সেস করতে চান আপনি এই জাতীয় কিছু করতে পারেন:

// 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 

13

পূর্ববর্তী পোস্টের জন্য ধন্যবাদ, আমি একটি অ্যাসিঙ্ক্রোনাস ইভেন্টের সাথে আমার মডেলটি আপডেট করতে পারি।

<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;
    });
};

6

আরও নিরাপদ এবং পারফরম্যান্ট উপায় বিশেষত যখন ডিবাগ ডেটা বন্ধ থাকে তা হ'ল একটি কলব্যাক ফাংশন ধরে রাখতে একটি ভাগ করা ভেরিয়েবল ব্যবহার করা। আপনার কৌণিক নিয়ামক এই ফাংশনটির অভ্যন্তরীণ বাহ্যিক কোডে ফিরিয়ে আনতে এটি প্রয়োগ করে।

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;
}
}]);

পুনরায় ব্যবহারযোগ্য নির্দেশিকা হিসাবে সাধারণীকরণ করা হয়েছে:

আমি একটি 'এক্সপোজস্কোপ' নির্দেশিকা তৈরি করেছি যা একই ধরণের ফ্যাশনে কাজ করে তবে ব্যবহারটি সহজ:

<div ng-controller="myController" expose-scope="aVariableNameForThisScope">
   <span expose-scope='anotherVariableNameForTheSameScope" />
</div>

এটি বর্তমান স্কোপটি (যা নির্দেশকের লিঙ্ক ফাংশনকে দেওয়া হয়) একটি বিশ্বব্যাপী 'স্কোপস' অবজেক্টে সংরক্ষণ করে যা সমস্ত স্কোপের জন্য ধারক। নির্দেশিক বৈশিষ্ট্যের সরবরাহিত মানটি এই বিশ্বব্যাপী অবজেক্টের স্কোপের সম্পত্তি নাম হিসাবে ব্যবহৃত হয়।

এখানে ডেমো দেখুন । আমি ডেমোতে যেমন দেখিয়েছি, বিশ্বব্যাপী 'স্কোপস' অবজেক্ট থেকে সুযোগটি সঞ্চিত এবং অপসারণ করা হলে আপনি 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>

মনে রাখবেন, আসল উপাদানটি যখন ডিওএম থেকে সরানো হয় তখন আমি অন ('স্কোপডেস্ট্রয়েড') পরীক্ষা করি নি। যদি এটি কাজ না করে, ইভেন্টটির পরিবর্তে ডকুমেন্টটিতে ইভেন্টটি ট্রিগার করা সাহায্য করতে পারে। (অ্যাপ্লিকেশন। js দেখুন) ডেমো প্লাঙ্কারের স্ক্রিপ্ট।


3

আমি জানি এটি একটি পুরানো প্রশ্ন তবে আমি সম্প্রতি এটি করার জন্য বিকল্পগুলির দিকে চেয়ে ছিলাম, তাই আমি ভেবেছিলাম যে এটি আমার কারও পক্ষে কার্যকর হলে আমার অনুসন্ধানগুলি এখানে রেখেছি।

বেশিরভাগ ক্ষেত্রে, যদি ইউআই এর স্থিতি বা অ্যাপ্লিকেশনটির অভ্যন্তরীণ কাজের সাথে যোগাযোগের জন্য বাহ্যিক উত্তরাধিকারের কোডের প্রয়োজন হয় তবে এই পরিষেবাগুলি পরিবর্তনগুলি বিমোচন করতে কোনও পরিষেবা কার্যকর হতে পারে। যদি কোনও বাহ্যিক কোড আপনার কৌনিক নিয়ামক, উপাদান বা নির্দেশের সাথে সরাসরি যোগাযোগ করে তবে আপনি আপনার লিগ্যাসি কোডের সাথে আপনার অ্যাপ্লিকেশনটিকে ভারীভাবে সংযুক্ত করছেন যা খারাপ খবর।

আমি আমার ক্ষেত্রে যা ব্যবহার করে শেষ করেছি তা হ'ল ব্রাউজার অ্যাক্সেসযোগ্য গ্লোবালগুলির (যেমন উইন্ডো) এবং ইভেন্ট হ্যান্ডলিংয়ের সংমিশ্রণ। আমার কোডটিতে একটি স্মার্ট ফর্ম জেনারেশন ইঞ্জিন রয়েছে যার ফর্মগুলি প্রারম্ভিক করার জন্য একটি সিএমএস থেকে জেএসএন আউটপুট প্রয়োজন। আমি যা করেছি তা এখানে:

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 ])

এবং আমার নিয়ন্ত্রকদের মধ্যে: ফাংশন () 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>

স্পষ্টতই প্রতিটি পদ্ধতিরই এর যোগ্যতা এবং ত্রুটি রয়েছে। এই পদ্ধতির সুবিধা এবং ব্যবহার আপনার ইউআইয়ের উপর নির্ভর করে। পূর্বে প্রস্তাবিত পদ্ধতিগুলি আমার ক্ষেত্রে কার্যকর হয় না কারণ আমার ফর্ম স্কিমা এবং উত্তরাধিকার কোডের কৌণিক স্কোপের কোনও নিয়ন্ত্রণ এবং জ্ঞান নেই। তাই আমাদের অ্যাপ্লিকেশনটির উপর ভিত্তি করে কনফিগার করা angular.element('element-X').scope(); যদি আমরা চারপাশে স্কোপগুলি পরিবর্তন করি তবে সম্ভাব্যভাবে অ্যাপ্লিকেশনটি ভেঙে দিতে পারে। তবে যদি আপনার অ্যাপ্লিকেশনটির স্কোপিংয়ের জ্ঞান থাকে এবং এটি প্রায়শই পরিবর্তিত হয় না তার উপর নির্ভর করতে পারেন, যা পূর্বে প্রস্তাবিত হয়েছিল তা একটি व्यवहार্য পন্থা।

আশাকরি এটা সাহায্য করবে. যে কোনও প্রতিক্রিয়াও স্বাগত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.