AngularJS। কন্ট্রোলার উপাদানগুলির বাইরে থেকে কীভাবে নিয়ন্ত্রণকারী ফাংশন কল করা যায়


190

ওয়েব পৃষ্ঠার যে কোনও জায়গা (নিয়ামক উপাদানগুলির বাইরে) থেকে নিয়ামকের অধীনে সংজ্ঞায়িত ফাংশনটিকে আমি কীভাবে বলতে পারি?

আমি "get" বোতাম টিপলে এটি পুরোপুরি কাজ করে। তবে আমাকে ডিভ কন্ট্রোলারের বাইরে থেকে কল করা দরকার। যুক্তিটি হ'ল: ডিফল্টরূপে আমার ডিভ লুকানো। নেভিগেশন মেনুতে কোথাও আমি একটি বোতাম টিপুন এবং এটি () আমার ডিভিটি দেখায় এবং "get" ফাংশনটি সম্পাদন করে। আমি কীভাবে এটি অর্জন করতে পারি?

আমার ওয়েব পৃষ্ঠাটি হ'ল:

<div ng-controller="MyController">
  <input type="text" ng-model="data.firstname" required>
  <input type='text' ng-model="data.lastname" required>

  <form ng-submit="update()"><input type="submit" value="update"></form>
  <form ng-submit="get()"><input type="submit" value="get"></form>
</div>

আমার জেএস:

   function MyController($scope) {
      // default data and structure
      $scope.data = {
        "firstname" : "Nicolas",
        "lastname" : "Cage"
      };

      $scope.get = function() {
        $.ajax({
           url: "/php/get_data.php?",
           type: "POST",
           timeout: 10000, // 10 seconds for getting result, otherwise error.
           error:function() { alert("Temporary error. Please try again...");},
           complete: function(){ $.unblockUI();},
           beforeSend: function(){ $.blockUI()},
           success: function(data){
            json_answer = eval('(' + data + ')');
            if (json_answer){
                $scope.$apply(function () {
                  $scope.data = json_answer;
            });
            }
        }
    });
  };

  $scope.update = function() {
    $.ajax({
        url: "/php/update_data.php?",
        type: "POST",
        data: $scope.data,
        timeout: 10000, // 10 seconds for getting result, otherwise error.
        error:function() { alert("Temporary error. Please try again...");},
        complete: function(){ $.unblockUI();},
        beforeSend: function(){ $.blockUI()},
        success: function(data){ }
      });
    };
   }

2
যখন আপনি "... কোথাও নেভিগেশন মেনুতে আপনি একটি বোতাম টিপুন ..." বলছেন, আপনি কি বোঝাতে চাইছেন যে এই নেভিগেশনটি অন্য একটি নিয়ামকের অংশ এবং আপনি get()অন্য নিয়ামকের কাছ থেকে মাইকন্ট্রোলারের কল করতে চান ?
কলমেকাট্টি

1
আপাতত নেভিগেশন মেনু কোনও নিয়ামক নয়। শুধু এইচটিএমএল। এইচটিএমএল / জাভাস্ক্রিপ্ট থেকে নিয়ন্ত্রক ফাংশন কল করা সম্ভব কিনা তা নিশ্চিত নই, কেন আমি এই প্রশ্নটি পোস্ট করেছি। তবে হ্যাঁ, পৃথক নিয়ন্ত্রক হিসাবে নেভিগেশন মেনু তৈরি করতে যৌক্তিক। নেভিগেশনমেনু.কন্ট্রোলার থেকে আমি কীভাবে MyController.get () ফাংশনটি কল করতে পারি?
পাভেল জাদারভ

উত্তর:


331

এটির বাইরে থেকে নিয়ন্ত্রকের ফাংশনটি কল করার একটি উপায় এখানে রয়েছে:

angular.element(document.getElementById('yourControllerElementID')).scope().get();

get()আপনার নিয়ামক থেকে একটি ফাংশন যেখানে ।

আপনি পরিবর্তন করতে পারেন

document.getElementById('yourControllerElementID')` 

প্রতি

$('#yourControllerElementID')

আপনি যদি jQuery ব্যবহার করছেন।

এছাড়াও, যদি আপনার ফাংশনটির অর্থ আপনার ভিউতে কিছু পরিবর্তন হয় তবে আপনার কল করা উচিত

angular.element(document.getElementById('yourControllerElementID')).scope().$apply();

পরিবর্তনগুলি প্রয়োগ করতে।

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

হালনাগাদ:

কৌণিকের সর্বশেষতম সংস্করণ সহ, আপনার ব্যবহার করা উচিত

angular.element(document.getElementById('yourControllerElementID')).injector().‌​get('$rootScope')

এবং হ্যাঁ, এটি প্রকৃতপক্ষে একটি খারাপ অভ্যাস , তবে কখনও কখনও আপনার কেবল দ্রুত এবং নোংরা কাজ করা প্রয়োজন।


30
এটিকে কোড গন্ধের মতো বলে মনে হচ্ছে যেহেতু
কৌণিকের দর্শনটি কৌনিক

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

3
আমি $applyকোনও ফাংশনে ..scope.$apply(function() { scope.get() });
কোডটি গুটিয়ে

2
আমি আসলে angular.element(document.getElementById('yourControllerElementID')).scope().controller; প্রাক্তন সহ কন্ট্রোলার অ্যাক্সেস করতে পারি । যদি ব্যবহার করুন: angular.element(document.getElementById('controller')).scope().get() ছোঁড়া এবং সংজ্ঞায়িত ত্রুটি, তবে আমি angular.element(document.getElementById('controller')).scope().controller.get()এটি ব্যবহার করি তবে কার্যকর হয়।
ভ্রুনোয়া

2
এটি কি সম্ভব, যে এই সমাধানটি আর কৌণিক 1.4.9 তে কাজ করে না? আমি অ্যাক্সেস করতে পারে না scope()যে angular.element(...), কারণ এটি undefined ফিরে যান এবং কৌণিক উপাদান / বস্তুর একটি vardump বলছেন যে ফাংশন, scopeমধ্যে অবস্থিত __proto__-object।
স্মাট্টি

37

আমি ইন্টারনেটে একটি উদাহরণ পেয়েছি।

কিছু লোক এই কোডটি লিখেছিল এবং নিখুঁতভাবে কাজ করেছে

এইচটিএমএল

<div ng-cloak ng-app="ManagerApp">
    <div id="MainWrap" class="container" ng-controller="ManagerCtrl">
       <span class="label label-info label-ext">Exposing Controller Function outside the module via onClick function call</span>
       <button onClick='ajaxResultPost("Update:Name:With:JOHN","accept",true);'>click me</button>
       <br/> <span class="label label-warning label-ext" ng-bind="customParams.data"></span>
       <br/> <span class="label label-warning label-ext" ng-bind="customParams.type"></span>
       <br/> <span class="label label-warning label-ext" ng-bind="customParams.res"></span>
       <br/>
       <input type="text" ng-model="sampletext" size="60">
       <br/>
    </div>
</div>

অবশ্যই JAVASCRIPT

var angularApp = angular.module('ManagerApp', []);
angularApp.controller('ManagerCtrl', ['$scope', function ($scope) {

$scope.customParams = {};

$scope.updateCustomRequest = function (data, type, res) {
    $scope.customParams.data = data;
    $scope.customParams.type = type;
    $scope.customParams.res = res;
    $scope.sampletext = "input text: " + data;
};



}]);

function ajaxResultPost(data, type, res) {
    var scope = angular.element(document.getElementById("MainWrap")).scope();
    scope.$apply(function () {
    scope.updateCustomRequest(data, type, res);
    });
}

ডেমো

* আমি কিছু পরিবর্তন করেছি, মূল দেখুন: ফন্ট জেএসফিডাল


2
ধন্যবাদ রজার, খুব উপকারী!
এডুয়ার্ডো

লিগ্যাসি jQuery বৈধতা লাইব্রেরি সঙ্গে কাজ করা যা ব্যবহার করা আবশ্যক। সুতরাং, এটি হয় 1: লাইব্রেরিটি পুনরায় লেখুন, 2: গ্রন্থাগারটি মোড়ানোর জন্য নির্দেশিকা তৈরি করুন, বৈধ হওয়ার সময় কৌণিক জমা দেওয়ার জন্য কোডের 3: 2 টি লাইন ...
মাইকেল কে

আমি যদি অ্যাপ্লিকেশন ব্যবহার না করি তবে ফাংশনটি যা ভিউ ডেটা আপডেট করবে তা প্রতিফলিত হবে না?
মনোজিৎ সরকার

13

সমাধানটি angular.element(document.getElementById('ID')).scope().get()আমার পক্ষে কৌণিক 1.5.1.2 এ কাজ বন্ধ করে দিয়েছে। সমবডি একটি মন্তব্যে উল্লেখ করেছেন যে এটি 1.4.9 এও কাজ করে না। আমি বিশ্বব্যাপী ভেরিয়েবলে সুযোগটি সংরক্ষণ করে এটি স্থির করেছি:

var scopeHolder;
angular.module('fooApp').controller('appCtrl', function ($scope) {
    $scope = function bar(){
        console.log("foo");        
    };
    scopeHolder = $scope;
})

কাস্টম কোড থেকে কল:

scopeHolder.bar()

আপনি যদি কেবল এই পদ্ধতিতে সুযোগটি সীমাবদ্ধ করতে চান তবে। পুরো সুযোগের এক্সপোজার হ্রাস করতে। নিম্নলিখিত কৌশল ব্যবহার করুন।

var scopeHolder;
angular.module('fooApp').controller('appCtrl', function ($scope) {
    $scope.bar = function(){
        console.log("foo");        
    };
    scopeHolder = $scope.bar;
})

কাস্টম কোড থেকে কল:

scopeHolder()

এটি আমার জন্য দুর্দান্ত কাজ করেছে (এমনকি কোনও উপাদানগুলির অভ্যন্তর থেকেও)। আমার দৃশ্যে আমি এড়াতে পারছি না এমন "" বাইরের কৌণিক দিক থেকে কৌণিক স্টাফ ডাকার খারাপ অভ্যাস "ব্যতীত অন্য কাজ করার কি কোনও খারাপ দিক রয়েছে? stackoverflow.com/questions/42123120/...
RichC

ধন্যবাদ স্যার আপনার সাহায্যের জন্য আমি কিছুক্ষণের জন্য এর সমাধান
ইব্রাহিম আমের

11

দিমিত্রি এর উত্তর ভাল কাজ করে। আমি একই কৌশলটি ব্যবহার করে একটি সাধারণ উদাহরণ তৈরি করেছি।

জেএসফিডাল: http://jsfiddle.net/o895a8n8/5/

<button onclick="call()">Call Controller's method from outside</button>
<div  id="container" ng-app="" ng-controller="testController">
</div>

function call() {
    var scope = angular.element(document.getElementById('container')).scope();
      scope.$apply(function(){
        scope.msg = scope.msg + ' I am the newly addded message from the outside of the controller.';
    })
    alert(scope.returnHello());
}

function testController($scope) {
    $scope.msg = "Hello from a controller method.";
    $scope.returnHello = function() {
        return $scope.msg ; 
    }
}

7

আমি বরং কারখানাকে তাদের নিজস্ব কোডের লাইনের সাথে ইনজেক্ট করার চেয়ে নিয়ন্ত্রণকারীদের উপর নির্ভরতা হিসাবে অন্তর্ভুক্ত করব: http://jsfiddle.net/XqDxG/550/

myModule.factory('mySharedService', function($rootScope) {
    return sharedService = {thing:"value"};
});

function ControllerZero($scope, mySharedService) {
    $scope.thing = mySharedService.thing;

কন্ট্রোলরজিরো $


হুম। @ অ্যান্টন নীচে একটি ফিডল মন্তব্য করেছেন (মে '13 তে) যা দু'টি করে।
জেসি চিশলম

5

আপনার মেনুটি কোনও যুক্ত স্কোপ ছাড়াই যাওয়ার সঠিক উপায় কিনা তা বিবেচনা করার মতো হতে পারে। এটি আসলে কৌণিক উপায় নয়।

তবে, যদি আপনার এই পথে যেতে হয় তবে আপনি ইভেন্টগুলি প্রেরণে $ রুটস্কোপে ফাংশন যুক্ত করে those ফাংশনগুলির মধ্যে $ সম্প্রচারটি ব্যবহার করে এটি করতে পারেন। আপনার নিয়ামক তখন events ইভেন্টগুলি শোনার জন্য ব্যবহার করে।

অন্য সুযোগটি বিবেচনা করার মতো যদি আপনি কোনও সুযোগ ছাড়াই আপনার মেনুটি শেষ করেন তবে তা হ'ল যদি আপনার একাধিক রুট থাকে তবে আপনার সমস্ত কন্ট্রোলারের নিজস্ব আপ্যাট থাকতে হবে এবং ফাংশনগুলি পেতে হবে। (এটি ধরে নিচ্ছে আপনার একাধিক কন্ট্রোলার রয়েছে)


আপনি কীভাবে কন্ট্রোলটার দুটি থেকে কন্ট্রোলঅন এর .get () ফাংশন কল করতে পারেন তার কোনও সাধারণ উদাহরণ দিতে পারেন? আমার যুক্তিটি তাই প্রতিটি নিয়ন্ত্রকের নিজস্ব .get () .আপডেট () ফাংশন থাকবে। আমার মেইনমেনু কন্ট্রোলার থাকবে যা থেকে আমার প্রয়োজনীয় কন্ট্রোলারের (মেনু আইটেম অনুসারে) .get () চালানো দরকার।
পাভেল জাদারভ

পিএস, আমার কোড নয়, তবে এটি দেখায় যে কীভাবে একাধিক কনট্রোলারদের কার্যকারিতা ভাগ করে নেওয়া যায়
আন্তন

4

আমি $ http নিয়ে কাজ করতে ব্যবহার করি, যখন কোনও উত্স থেকে কিছু তথ্য পেতে চাইলে আমি নিম্নলিখিতটি করি:

angular.module('services.value', [])

.service('Value', function($http, $q) {

var URL = "http://localhost:8080/myWeb/rest/";

var valid = false;

return {
    isValid: valid,
    getIsValid: function(callback){
        return $http.get(URL + email+'/'+password, {cache: false})
                    .success(function(data){
            if(data === 'true'){ valid = true; }
        }).then(callback);
    }}
    });

এবং নিয়ামকের কোড:

angular.module('controllers.value', ['services.value'])

.controller('ValueController', function($scope, Value) {
    $scope.obtainValue = function(){
        Value.getIsValid(function(){$scope.printValue();});
    }

    $scope.printValue = function(){
        console.log("Do it, and value is " Value.isValid);
    }
}

কন্ট্রোলারে কোন ফাংশনটি কল করতে হবে সেই পরিষেবাতে আমি প্রেরণ করি


3

আমার একাধিক রুট এবং একাধিক কন্ট্রোলার রয়েছে, তাই আমি কাজের স্বীকৃত উত্তর পেতে পারি না। আমি দেখতে পেলাম যে উইন্ডোতে ফাংশন যুক্ত করা কাজ করে:

fooModule.controller("fooViewModel", function ($scope, fooService, $http, $q, $routeParams, $window, $location, viewModelHelper, $interval) {
    $scope.initFoo = function () {
        // do angular stuff
    }
    var initialize = function () {
        $scope.initFoo();
    }

    initialize();

    window.fooreinit = initialize;

}

তারপরে নিয়ন্ত্রকের বাইরে, এটি করা যেতে পারে:

function ElsewhereOnThePage() {
    if (typeof(fooreinit) == 'function') { fooreinit(); }
}

0

নিয়ামকের বাইরে থেকে কৌনিক স্কোপ ফাংশন কল করুন।

// Simply Use "Body" tag, Don't try/confuse using id/class.

var scope = angular.element('body').scope();             
scope.$apply(function () {scope.YourAngularJSFunction()});      

-1

আমি একটি আয়নিক কাঠামো ব্যবহারকারী এবং আমি খুঁজে পেয়েছি যে ধারাবাহিকভাবে বর্তমান নিয়ামকের $ সুযোগ সরবরাহ করবে:

angular.element(document.querySelector('ion-view[nav-view="active"]')).scope()

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

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