बाहरी js फ़ंक्शन से AngularJS एक्सेस स्कोप


131

मैं यह देखने की कोशिश कर रहा हूं कि क्या बाहरी जावास्क्रिप्ट फ़ंक्शन के माध्यम से नियंत्रक के आंतरिक दायरे तक पहुंचने का एक सरल तरीका है (लक्ष्य नियंत्रक के लिए पूरी तरह अप्रासंगिक)

मैंने यहाँ कुछ अन्य प्रश्नों पर देखा है

angular.element("#scope").scope();

DOM तत्व से स्कोप को पुनः प्राप्त करेंगे, लेकिन मेरे प्रयास वर्तमान में कोई उचित परिणाम नहीं दे रहे हैं।

यहाँ है jsfiddle: http://jsfiddle.net/sXkjc/5/

मैं वर्तमान में सादे जेएस से कोणीय में संक्रमण से गुजर रहा हूं। मुख्य कारण मैं इसे प्राप्त करने की कोशिश कर रहा हूं ताकि मेरे मूल पुस्तकालय कोड को यथासंभव बरकरार रखा जा सके; नियंत्रक के लिए प्रत्येक फ़ंक्शन को जोड़ने के लिए मेरी आवश्यकता को सहेजना।

इस बारे में कोई विचार कि मैं इसे कैसे प्राप्त कर सकता हूं? उपरोक्त फिडेल पर टिप्पणियाँ भी स्वागत योग्य हैं।


FYI करें डॉक्स के अनुसार .scope()डीबग डेटा को सक्षम करने की आवश्यकता होती है, लेकिन उत्पादन में डीबग डेटा का उपयोग गति के कारणों के लिए अनुशंसित नहीं है। नीचे दिए गए समाधान घूमते प्रतीत होते हैंscope()
rtpHarry

@rtpHarry सही है। नीचे दिए गए उत्तर जिसमें गुंजाइश () का उपयोग आवश्यक है। मेरा जवाब यहाँ देखें stackoverflow.com/a/34078750/319302
Cagatay Kalan

जवाबों:


223

आपको $ गुंजाइश का उपयोग करने की आवश्यकता है यदि आप एक jquery / javascript इवेंट हैंडलर जैसे angularjs के नियंत्रण के बाहर से किसी मान के मान में कोई बदलाव करना चाहते हैं।

function change() {
    alert("a");
    var scope = angular.element($("#outer")).scope();
    scope.$apply(function(){
        scope.msg = 'Superhero';
    })
}

डेमो: फिडल


2
@ dk123 angular.element("#scope")काम नहीं कर रहा है, हालांकि angular.element($("#scope"))काम कर रहा है, आपको jquery भी करनी होगी
अरुण पी जॉनी

1
मुझे पता है कि यह थोड़ी देर हो गई है, लेकिन मुझे उम्मीद है कि कुछ मुझे इस पर जवाब दे सकते हैं ... क्यों var गुंजाइश = angular.element ($ ("# बाहरी"))। गुंजाइश (); परिवर्तन समारोह के अंदर घोषित किया जाना है? अगर मैं इसे वैश्विक स्थान पर ले जाऊं तो यह एक रास्ता नहीं है?
मार्क एम।

1
@MarcM। मुझे लगता है कि यह एंगुलर के स्कोप रिक्रिएशन के साथ करना है। जब तक आप परिवर्तन फ़ंक्शन का उपयोग कर रहे हैं, तब तक वैश्विक स्कोप का पिछला स्कोप इंगित कर रहा था कि वह अब मौजूद नहीं हो सकता (मनोरंजन के कारण)।
dk123

1
angular.element ($ ( "div [एनजी नियंत्रक = 'myCtrl']")) गुंजाइश ()।; div तत्व में अतिरिक्त # राउटर से बेहतर है, मुझे लगता है
wyverny

1
जब हम करते हैं तो गुंजाइश () अपरिभाषित हो जाती है: $ compileProvider.debugInfoEnabled (झूठा); कोणीय में। तो हम इसे डिबगिनफो के साथ कैसे काम कर सकते हैं।
अज्ञेय

26

इस प्रश्न को पोस्ट किए हुए कुछ समय हो गया है, लेकिन इन विचारों को देखते हुए यह अभी भी लगता है, यहाँ एक और समाधान है जो मुझे इन कुछ वर्षों के दौरान आया है:

$scope.safeApply = function( fn ) {
    var phase = this.$root.$$phase;
    if(phase == '$apply' || phase == '$digest') {
        if(fn) {
            fn();
        }
    } else {
        this.$apply(fn);
    }
};

उपरोक्त कोड मूल रूप से एक समारोह कहा जाता है बनाता है safeApplyकि कैलेस $applyसमारोह (के रूप में अरुण के जवाब में कहा गया है) तभी कोणीय वर्तमान के माध्यम से नहीं जा रहा है$digest मंच। दूसरी ओर, अगर एंगुलर वर्तमान में चीजों को पचा रहा है, तो यह केवल फ़ंक्शन को निष्पादित करेगा जैसा कि है, क्योंकि परिवर्तन करने के लिए कोणीय को संकेत देने के लिए पर्याप्त होगा।

$applyफ़ंक्शन का उपयोग करने की कोशिश करते समय कई त्रुटियां होती हैं, जबकि एंगुलरज वर्तमान में अपने $digestचरण में हैं। इस safeApplyतरह की त्रुटियों को रोकने के लिए उपरोक्त कोड एक सुरक्षित आवरण है।

(नोट: मैं व्यक्तिगत safeApplyरूप से $rootScopeसुविधा प्रयोजनों के लिए एक समारोह के रूप में चक करना चाहता हूं )

उदाहरण:

function change() {
    alert("a");
    var scope = angular.element($("#outer")).scope();
    scope.safeApply(function(){
        scope.msg = 'Superhero';
    })
}

डेमो: http://jsfiddle.net/sXkjc/227/


1
आपका सुरक्षित काम क्यों करता है? लगता है कि आप जो कह रहे हैं, "यदि फंक्शन अपने आप में फंक्शन को अंजाम दे रहा है, अगर एंगुलर $ अप् या $ डाइजेस्ट स्टेज में है, तो फंक्शन लगाने के लिए $ अप्लाई () का इस्तेमाल करें" .... लेकिन अगर आप फंक्शन को खुद ही एग्जीक्यूट करते हैं .. .. कि कैसे किसी भी मॉडल को अद्यतन करता है? ऐसा लगता है कि अनुकूल व्यवहार नहीं होगा, जब तक कि वहाँ कुछ चल रहा है जिसके बारे में मुझे नहीं पता है। क्या एंगुलर में कुछ मैकेनिज्म उन बदलावों के लिए $ गुंजाइश बना देता है जो सीधे उसके साथ हुए हैं?
trusktr

इसके अलावा, अगर आपको उन राज्यों के खिलाफ सुरक्षा की आवश्यकता है, तो मैं इस बात पर विचार करूंगा कि $ लागू () पद्धति का एक बग जिसे ठीक करने की आवश्यकता है।
trusktr

@trusktr मैं जो भी समझता हूं, फ़ंक्शन को सामान्य रूप से निष्पादित करना कोणीय द्वारा पकड़ा जाता है यदि फ़ंक्शन किसी भी मॉडल को बदलता है, और इसलिए कोणीय उन्हें अगले पाचन चरण में अपडेट करता है।
dk123

@trusktr मैं इस बात से सहमत हूँ कि अगर सुरक्षा उपायों के बिना सामान्य $ लागू () लागू किया जा सकता है, तो बेहतर कुछ नहीं होगा। संक्षेप में, safeApply का एकमात्र उद्देश्य $ लागू () त्रुटियों के विरुद्ध सुरक्षा करना है। निश्चित नहीं है कि अगर यह एक रिपोर्ट किया गया मुद्दा था और अब तय हो गया है, या अभी भी चल रहा है।
dk123

1
सिर्फ इसलिए कि मैंने इस पर ठोकर खाई: github.com/angular/angular.js/wiki/When-to-use-$scope.$apply () । _ यदि आप कर रहे हैं ((! $ स्कोप। $$ चरण) $ स्कोप। $ लागू करें () यह इसलिए है क्योंकि आप कॉल स्टैक में पर्याप्त उच्च नहीं हैं ।_
scheffield

17

ऐसा करने का एक और तरीका है:

var extScope;
var app = angular.module('myApp', []);
app.controller('myController',function($scope, $http){
    extScope = $scope;
})
//below you do what you want to do with $scope as extScope
extScope.$apply(function(){
    extScope.test = 'Hello world';
})

1
मुझे अभी भी समझ नहीं आया कि यह टिप्पणी इसके लिए सबसे अच्छा जवाब क्यों नहीं है। निराशा और क्रोध के साथ, कुछ दिनों के लिए इंटरनेट खोदने के बाद, आखिरकार यही मेरे मुद्दे को हल किया है। साभार @Charleston आप महान हैं, सर!
राजकुमार

13

हम लोड होने के बाद इसे कॉल कर सकते हैं

http://jsfiddle.net/gentletech/s3qtv/3/

<div id="wrap" ng-controller="Ctrl">
    {{message}}<br>
    {{info}}
    </div>
    <a  onClick="hi()">click me </a>

    function Ctrl($scope) {
        $scope.message = "hi robi";
        $scope.updateMessage = function(_s){
            $scope.message = _s;    
        };
    }

function hi(){
    var scope = angular.element(document.getElementById("wrap")).scope();
        scope.$apply(function() {
        scope.info = "nami";
        scope.updateMessage("i am new fans like nami");
    });
}

8

यह प्रश्न पूछे हुए मुझे एक लंबा समय हो गया है, लेकिन यहाँ एक उत्तर दिया गया है जिसमें jquery की आवश्यकता नहीं है:

function change() {
    var scope = angular.element(document.querySelector('#outside')).scope();
    scope.$apply(function(){
        scope.msg = 'Superhero';
    })
}

3

यहाँ एक पुन: प्रयोज्य समाधान है: http://jsfiddle.net/flobar/r28b0gmq/

function accessScope(node, func) {
    var scope = angular.element(document.querySelector(node)).scope();
    scope.$apply(func);
}

window.onload = function () {

    accessScope('#outer', function (scope) {
        // change any property inside the scope
        scope.name = 'John';
        scope.sname = 'Doe';
        scope.msg = 'Superhero';
    });

};

2

आप भी आजमा सकते हैं:

function change() {
    var scope = angular.element( document.getElementById('outer') ).scope();
    scope.$apply(function(){
        scope.msg = 'Superhero';
    })
}

@ dk123 इसे भी JQuery की आवश्यकता नहीं है।
कठोर शर्मा

1

स्वीकृत उत्तर महान है। मैं देखना चाहता था कि के संदर्भ में कोणीय क्षेत्र का क्या होता है ng-repeat। बात यह है, कोणीय प्रत्येक दोहराया आइटम के लिए एक उप-गुंजाइश बनाएगा। मूल पर परिभाषित विधि में कॉल करते समय $scope, यह मूल मूल्य (जावास्क्रिप्ट बंद होने के कारण) को बरकरार रखता है। हालाँकि, thisकॉलिंग स्कोप / ऑब्जेक्ट को संदर्भित करता है। यह अच्छी तरह से इतने लंबे समय आप जब पर स्पष्ट कर रहे हैं के रूप में बाहर काम करता है, $scopeऔर thisएक ही हैं और जब वे अलग हैं। hth

यहाँ एक फिडेल है जो अंतर दिखाता है: https://jsfiddle.net/creitzel/oxsxjcyc/


1

मैं नौसिखिया हूं, इसलिए यदि कोई बुरा व्यवहार है तो क्षमा करें। चुने हुए उत्तर के आधार पर, मैंने यह कार्य किया:

function x_apply(selector, variable, value) {
    var scope = angular.element( $(selector) ).scope();
    scope.$apply(function(){
        scope[variable] = value;
    });
}

मैं इसे इस तरह से उपयोग कर रहा हूं:

x_apply('#fileuploader', 'thereisfiles', true);

वैसे, मेरी अंग्रेजी के लिए खेद है


0
<input type="text" class="form-control timepicker2" ng-model='programRow.StationAuxiliaryTime.ST88' />

प्रवेश मान

मान लें कि programRow.StationAuxiliaryTime ऑब्जेक्ट की एक सरणी है

 $('.timepicker2').on('click', function () 
    {
            var currentElement = $(this);

            var scopeValues = angular.element(currentElement).scope();
            var model = currentElement.attr('ng-model');
            var stationNumber = model.split('.')[2];
            var val = '';
            if (model.indexOf("StationWaterTime") > 0) {
                val = scopeValues.programRow.StationWaterTime[stationNumber];
            }
            else {
                val = scopeValues.programRow.StationAuxiliaryTime[stationNumber];
            }
            currentElement.timepicker('setTime', val);
        });

0

हमें फंक्शन $ में निर्मित एंगुलर जेएस का उपयोग करने की आवश्यकता है, जो कि कंट्रोलर फंक्शन के बाहर स्कोप या वैरिएबल पर लागू होता है।

इसे दो तरीकों से किया जा सकता है :

| * | विधि 1: आईडी का उपयोग:

<div id="nameNgsDivUid" ng-app="">
    <a onclick="actNgsFnc()"> Activate Angular Scope</a><br><br>
    {{ nameNgsVar }}
</div>

<script type="text/javascript">

    var nameNgsDivVar = document.getElementById('nameNgsDivUid')

    function actNgsFnc()
    {
        var scopeNgsVar = angular.element(nameNgsDivVar).scope();
        scopeNgsVar.$apply(function()
        {
            scopeNgsVar.nameNgsVar = "Tst Txt";
        })
    }

</script>

| * | विधि 2: एनजी-नियंत्रक के init का उपयोग करना:

<div ng-app="nameNgsApp" ng-controller="nameNgsCtl">
    <a onclick="actNgsFnc()"> Activate Angular Scope</a><br><br>
    {{ nameNgsVar }}
</div>

<script type="text/javascript">

    var scopeNgsVar;
    var nameNgsAppVar=angular.module("nameNgsApp",[])
    nameNgsAppVar.controller("nameNgsCtl",function($scope)
    {
        scopeNgsVar=$scope;
    })

    function actNgsFnc()
    {
        scopeNgsVar.$apply(function()
        {
            scopeNgsVar.nameNgsVar = "Tst Txt";
        })
    }

</script>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.