136

外部JavaScript関数を介してコントローラーの内部スコープにアクセスする簡単な方法があるかどうかを確認しようとしています(ターゲットコントローラーとは完全に無関係です)

ここで他のいくつかの質問を見てきました

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

DOM要素からスコープを取得しますが、私の試みは現在適切な結果をもたらしていません.

これがjsfiddleです:http://jsfiddle.net/sXkjc/5/

私は現在、プレーン JS から Angular への移行を行っています。これを達成しようとしている主な理由は、元のライブラリ コードを可能な限りそのままにしておくことです。各機能をコントローラーに追加する必要がなくなりました。

これを達成する方法についてのアイデアはありますか? 上記のフィドルに関するコメントも歓迎します。

4

12 に答える 12

230

jquery/javascript イベント ハンドラーのように angularjs の制御外からスコープ値を変更する場合は、$scope.$apply()を使用する必要があります。

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

デモ:フィドル

于 2013-03-15T04:54:24.063 に答える
26

この質問を投稿してからしばらく経ちましたが、これがまだ得られているように見えるビューを考慮して、ここ数か月の間に私が見つけた別の解決策を次に示します。

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

上記のコードは基本的に、 Angular のみが現在ステージを通過していない場合に、(Arun の回答に記載されているように) 関数safeApplyを呼び出す関数を作成します。一方、Angularが現在物事を消化している場合、Angular に変更を加えるように通知するのに十分であるため、関数をそのまま実行します。$apply$digest

$applyAngularJs が現在$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/

于 2013-08-16T03:19:09.173 に答える
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';
})
于 2015-06-23T01:06:21.680 に答える
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");
    });
}
于 2013-09-12T07:52:00.600 に答える
8

この質問をしてから長い時間が経ちましたが、jquery を必要としない回答を次に示します。

function change() {
    var scope = angular.element(document.querySelector('#outside')).scope();
    scope.$apply(function(){
        scope.msg = 'Superhero';
    })
}
于 2014-07-28T07:10:27.590 に答える
1

受け入れられた答えは素晴らしいです。のコンテキストで Angular スコープに何が起こるかを調べたかったのですng-repeat。問題は、Angular が繰り返されるアイテムごとにサブスコープを作成することです。元の で定義されたメソッドを呼び出すと$scope、元の値が保持されます (javascript の閉鎖のため)。ただし、this呼び出しスコープ/オブジェクトを参照します。$scopeいつとthisが同じで、いつ が異なるかを明確にしている限り、これはうまくいきます。h番目

違いを示すフィドルは次のとおりです。https://jsfiddle.net/creitzel/oxsxjcyc/

于 2015-05-07T14:45:37.373 に答える
1

私は初心者なので、悪い習慣である場合は申し訳ありません。選択した回答に基づいて、次の機能を実行しました。

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

私はこのように使用しています:

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

ところで、私の英語でごめんなさい

于 2016-08-02T05:07:39.023 に答える
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);
        });
于 2015-06-30T05:16:23.843 に答える