195

コントローラーで定義された関数を Web ページの任意の場所 (コントローラー コンポーネントの外部) から呼び出すにはどうすればよいですか?

「取得」ボタンを押すと完全に機能します。しかし、div コントローラーの外部から呼び出す必要があります。ロジックは次のとおりです。デフォルトでは、私の div は非表示になっています。ナビゲーション メニューのどこかでボタンを押すと、div が表示され、「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>

私のjs:

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

10 に答える 10

37

インターネットで例を見つけました。

誰かがこのコードを書き、完璧に動作しました

HTML

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

ジャバスクリプト

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

デモ

*いくつかの変更を加えました。オリジナルを参照してください: font JSfiddle

于 2015-01-30T15:06:56.020 に答える
7

独自のコード行を注入するよりも、コントローラーの依存関係としてファクトリーを含めたいと思います: http://jsfiddle.net/XqDxG/550/

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

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

ControllerZero.$inject = ['$scope', 'mySharedService'];

于 2013-09-20T16:20:14.103 に答える
5

スコープが関連付けられていないメニューを使用することが正しい方法であるかどうかを検討する価値があるかもしれません。それは本当に角度のある方法ではありません。

ただし、それが必要な場合は、関数を $rootScope に追加し、それらの関数内で $broadcast を使用してイベントを送信することで実行できます。次に、コントローラーは $on を使用してこれらのイベントをリッスンします。

スコープのないメニューを作成する場合に考慮すべきもう 1 つのことは、複数のルートがある場合、すべてのコントローラーに独自の更新機能と取得機能が必要になることです。(これは、複数のコントローラーがあることを前提としています)

于 2013-05-23T09:14:16.023 に答える
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);
    }
}

コントローラーで呼び出す必要がある関数をサービスに送信します

于 2014-04-11T09:41:37.230 に答える
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(); }
}
于 2015-06-18T16:34:59.953 に答える
-1

私は Ionic フレームワークのユーザーであり、現在のコントローラーの $scope を一貫して提供することがわかったのは次のとおりです。

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

特定のコントローラー インスタンスでのみ使用可能な特定の DOM 要素を対象とするクエリを見つけることで、フレームワークに関係なく (またはフレームワークに関係なく) ほとんどのシナリオに適合するようにこれを変更できると思います。

于 2016-06-24T15:10:17.343 に答える