외부 js 함수의 AngularJS 액세스 범위


131

외부 자바 스크립트 함수를 통해 컨트롤러의 내부 범위에 액세스하는 간단한 방법이 있는지 확인하려고합니다 (대상 컨트롤러와 완전히 관련이 없음)

나는 여기에 몇 가지 다른 질문을 보았습니다.

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

DOM 요소에서 범위를 검색하지만 현재 시도한 결과가 적절하지 않습니다.

jsfiddle은 다음과 같습니다. http://jsfiddle.net/sXkjc/5/

나는 현재 일반 JS에서 Angular 로의 전환을 겪고 있습니다. 이것을 달성하려는 주된 이유는 원래 라이브러리 코드를 가능한 한 손상시키지 않는 것입니다. 각 기능을 컨트롤러에 추가 할 필요가 없습니다.

이것을 달성하는 방법에 대한 아이디어가 있습니까? 위의 바이올린에 대한 의견도 환영합니다.


사용하는 문서에 따르면 FYI .scope()는 디버그 데이터를 활성화해야하지만 프로덕션에서 디버그 데이터를 사용하는 것은 속도상의 이유로 권장되지 않습니다 . 아래의 솔루션은 다음과 같이 회전하는 것으로 보입니다scope()
rtpHarry

@rtpHarry가 맞습니다. scope ()를 사용해야하는 아래 답변은 더 이상 사용되지 않습니다. 내 답변보기 here stackoverflow.com/a/34078750/319302
Cagatay Kalan

답변:


223

jquery / javascript 이벤트 핸들러와 같이 angularjs의 제어 외부에서 범위 값을 변경 하려면 $ scope. $ apply () 를 사용해야합니다.

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도 필요합니다.
Arun P Johny

1
나는 그것이 오래되었다는 것을 알고 있지만 일부는 이것에 대해 대답 할 수 있기를 바랍니다 ... 왜 var scope = angular.element ($ ( "# outer")). scope (); change 함수 안에 선언해야합니까? 지구 공간으로 옮기면 안돼요?
Marc M.

1
@MarcM. Angular의 스코프 레크리에이션과 관련이 있다고 생각합니다. change 함수를 사용할 때 전역 var가 가리키고 있던 이전 범위가 더 이상 존재하지 않을 수 있습니다 (레크리에이션으로 인해).
dk123

1
angular.element ($ ( "div [ng-controller = 'myCtrl']")). scope (); 더 추가 #outer보다 DIV 요소 인 것 같아요
wyverny

1
scope ()은 다음과 같이 할 때 정의되지 않습니다 : $ compileProvider.debugInfoEnabled (false); 각도로. 어떻게 debuginfoEnabled false로 작동하게 할 수 있습니까?
Agnosco

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 단계. 반면에 Angular 가 현재 소화하고 있다면 , 기능을 그대로 실행합니다. Angular에 신호를 보내서 변경하기에 충분하기 때문입니다.

$applyAngularJ가 현재 $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
safeApply 기능이 작동하는 이유는 무엇입니까? 당신이 말하는 것은 "Angular가 $ apply 또는 $ digest 단계이면 함수 자체를 실행하고 그렇지 않으면 $ apply ()를 사용하여 함수를 적용하는 것"입니다. .. 어떻게 모델을 업데이트합니까? 내가 알지 못하는 일이 없다면 그런 행동은 유리하지 않을 것 같습니다. Angular의 일부 메커니즘은 $ scope에 직접 발생했을 수있는 변경 사항을 폴링합니까 ???
trusktr

또한 해당 상태를 보호 해야하는 경우 수정 해야하는 $ apply () 메서드의 버그를 고려할 것입니다.
trusktr

@trusktr 내가 이해하는 것에서 함수가 모델을 변경하면 함수가 정상적으로 각도에 의해 잡히므로 각도는 다음 다이제스트 단계에서 업데이트됩니다.
dk123

@trusktr 나는 보호 수단없이 정상적인 $ apply ()를 적용 할 수 있다면 더 좋은 것은 없다는 것에 동의합니다. 본질적으로 safeApply의 유일한 목적은 $ apply () 오류를 방지하는 것입니다. 이것이보고 된 문제였으며 현재 해결되었거나 여전히 진행중인 문제인지 확실하지 않습니다.
dk123

1
github.com/angular/angular.js/wiki/When-to-use-$scope.$apply ()와 같이 넘어졌습니다 . _ (! $ scope. $$ phase) $ scope. $ apply () if 호출하는 경우 호출 스택에서 충분히 높지 않기 때문입니다 ._
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에게 감사합니다. 당신은 위대합니다!
Rajkumar

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가 필요하지 않습니다.
harish sharma

1

받아 들여진 대답은 훌륭합니다. 의 맥락에서 각도 범위에 어떤 일이 일어나는지보고 싶었습니다 ng-repeat. 문제는 Angular는 반복되는 각 항목에 대해 하위 범위를 만듭니다. original에 정의 된 메소드를 호출 할 때 $scope(JavaScript 클로저로 인해) 원래 값을 유지합니다. 그러나 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

함수 $ apply에 내장 된 Angular J를 사용해야 합니다컨트롤러 함수 외부의 스코프 변수 또는 함수를 획득 합니다.

이것은 두 가지 방법으로 수행 할 수 있습니다.

| * | 방법 1 : ID 사용 :

<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 : ng-controller 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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.