Bruno Oliveira
Bruno Oliveira

Reputation: 745

Calling a function outside the scope of an Angular app

I have the following Angular code:

app.controller('MainCtrl', function($rootScope, $http) {

    $rootScope.graph = {'width': '100%', 'height': 500};
    $rootScope.rectangles = [
        //     {'x':220,  'y':220,  'width' : 300, 'height' : 100},
        // {'x':520,  'y':220,  'width' : 10, 'height' : 10},
        //valid JSON:  {"rect":{"x":220,  "y":220,  "width" : 300, "height" : 100}, "info":""}
    ];

//more code

As you can see, I have an application composed of a single module, single controller.

I have a function whose purpose (with other helper functions) is to populate the array rectangles. That function is called DrawMatrix.

On the HTML side, the code that uses this function is as follows:

 <div id="body">
    <div ng-controller="MainCtrl" ng-app="app">
        <div class="col-sm-6 col-md-6 col-lg-6" style="background-color: #D2D7D3">

            <div style="padding:25px;">

                <div class="col-sm-8 col-md-8 col-lg-8 input-group">
                    <span class="input-group-addon" id="basic-addon1">Number of questions:</span>
                    <input id="NumQuest" type="text" class="form-control" placeholder="Please enter number of questions..." aria-describedby="basic-addon1">
                </div>

                <div class="btn-group" role="group" aria-label="...">
                    <button ng-click="DrawMatrix(NumQuest)" type="button" class="btn btn-default">Draw</button>
                    <button ng-click="DelMatrix(NumQuest)" type="button" class="btn btn-default">Clean</button>
    //More code

Then, I also have, on my interface, a set of text boxes on which some actions are performed upon when you click on them, and, a code example of such actions is this:

var totalNumOfQuestions = 1;
//Actualizar NumQuest de acordo com a variavel indicada acima!!
$(function(){
    $(document).on('focus', 'div.form-group-options div.input-group-option:last-child input', function(){

        var sInputGroupHtml = $(this).parent().html();
        var sInputGroupClasses = $(this).parent().attr('class');
        $(this).parent().parent().append('<div class="'+sInputGroupClasses+'">'+sInputGroupHtml+'</div>');

        //Testes
       // alert( totalNumOfQuestions);
        var NumQuest=document.getElementById("NumQuest").value;
        //alert(NumQuest);
        var $body = angular.element(document.querySelector('body'));   // 1
        var $rootScope = $body.scope().$root;         // 2
        $rootScope.$apply(function () {               // 3
            $rootScope.DrawMatrix(1);
        });
        totalNumOfQuestions+=1;
        //fim
    });

As you might have noticed, what I want to do is:

When I click on one of the text boxes, instead of sending an alert as action, I want to trigger a call to the function that is defined inside the AngularJS controller.

Something like this seems close to what I want, but, I can't get it to work:

How to access/update $rootScope from outside Angular

I know it's bad practice and I could possibly use a service or injectors or something, but, I don't know it and I only need to make it work only for a single very particular functionality.

Any help will be appreciated.

Upvotes: 0

Views: 1688

Answers (2)

Samuel Coelho
Samuel Coelho

Reputation: 46

When I click on one of the text boxes, instead of sending an alert as action, I want to trigger a call to the function that is defined inside the AngularJS controller.

Why don't you just use ng-click or ng-focus attribute in your text boxes?

Upvotes: 3

AWolf
AWolf

Reputation: 8990

I think it's just your querySelector for $body variable that is at the wrong DOM element. It should be the element where you've added the ng-controller.

You could get it with:

var $rootScope = angular.element($('div[ng-controller="MainCtrl"]')).scope().$root;

Please have a look at the 'bad practice' example below or in this jsfiddle.

angular.module('demoApp', [])
    .controller('mainController', function ($rootScope) {
    $rootScope.dummy = 'Test\r\n';
    $rootScope.addText = function (text) {
        $rootScope.dummy += text + '\r\n';
    };
});

$(function () {

    $('#test').click(function () {
        var $rootScope = angular.element($('div[ng-controller="mainController"]')).scope().$root;

        $rootScope.$apply(function () {
            //scope.dummy += 'test'; // works
            $rootScope.addText('test');
        });
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController">
    <button id="test">test</button>
    <pre>{{dummy}}</pre>

</div>

Upvotes: 3

Related Questions