6

I have seen a lot of questions related to this matter but no solution I've tried is working:

Inside the folder public I have a file called app.js where I define my AngularJS application like this:

var app = angular.module('app', []);
var RectangleDim=30;

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

And in the end of the file I do the bootstrap like:

angular.bootstrap(document.getElementById('body'), ["app"]);

Then, inside the same folder and inside the HTML my entry point for the application of AngularJS is like this:

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

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

Then, on another folder, I have another JS file, where I need to call a specific function that is defined in the AngularJS code. The function is called Draw() and it is triggered when I click on an AngularJS button.

To simply call the function inside another file without clicking on any button I am doing something like this:

        var e = document.getElementById('body');
        var scope = angular.element(e).scope();
// update the model with a wrap in $apply(fn) which will refresh the view for us
        scope.$apply(function() {
            scope.Draw(NumQuest);
        });
        //fim

EDIT: In order to make my question a bit more clear, I can maybe add a few more details:

I only need to have one controller and a single module controlling my whole application because all the actions needed (which is calling 3 functions that update an SVG picture) are relatively self-contained, so I don't think there is any need to add complexity to the client-side code, which only might confuse me and other people working with me.

To recall what I need:

Inside a single app, with one controller, I have one function, Draw(someInputValue), that is generating an SVG figure. The input for this function is being received from a text input box.

On another file I have JS actions that are performed when I click on another text box (for example, show an alert or creating an additional text box). What I want is to associate a call to Draw(input) when I click on the text box.

Namely, I want to simulate the behaviour I have when I click on a button that reads a number from a text box and does some actions, but, instead, of having the input introduced by hand on a text box and clicking on a button, I want to simply click on a text box and perform the same action.

Bruno Oliveira
  • 735
  • 10
  • 20
  • 3
    Having to resort to fetching an angular scope through a DOM element is a code smell that you're maybe not using angular properly. Is there a specific reason for this architecture (i.e. why is this other file not an angular component)? – doldt Aug 29 '15 at 18:56
  • 1
    Adding a comment and up vote to @doldt. It is good practice to be aware of code smells. Usually when something is really ugly to solve it is outside of generic design principles and one should be super careful to take that route. Can't stress that enough hence the additional comment. For future readers of this topic, care to explain why you really need this? No other design solutions? – bastijn Aug 29 '15 at 20:24
  • 1
    What are you trying to accomplish here, using Angular to "not use Angular"? – Claies Aug 30 '15 at 00:03
  • 1
    @all, Regarding the project structure, I'm doing this project on my own, with the help of a friend and both of us are a bit inexperienced when it comes to web applications and that's why I have used SO so much. It might not be the best, but,it only needs to work, to be used by a few people in a closed environment context and nobody else will ever use the app. I am willing to learn the correct way, but, for now, I only want and need the prototype to work – Bruno Oliveira Aug 30 '15 at 10:18
  • 1
    Plus, that sort of "smelly" code thing, would only be used for a single specific functionality and nowhere else in the app, independent of everything else. – Bruno Oliveira Aug 30 '15 at 10:19

3 Answers3

3

In this case, you may wish to use $broadcast to relay your messages/data, and use $on to perform the action.

This practice should be limited, however, and used wisely to assure you don't have a noticeable performance hit down the road.

Working with $scope.$emit and $scope.$on

Community
  • 1
  • 1
AptitudeDude
  • 126
  • 4
2

HTML

<div id="YourElementId" ng-app='MyModule' ng-controller="MyController">
  Hi
</div>

JS Code

angular.module('MyModule', [])
    .controller('MyController', function ($scope) {
    $scope.myfunction = function (data) {
        alert("---" + data);
    };
});

window.onload = function () {
    angular.element(document.getElementById('YourElementId')).scope().myfunction('test');
}
SomeKittens
  • 38,868
  • 19
  • 114
  • 143
-1

I believe the Understanding Angular’s $scope and $rootScope event system $emit, $broadcast and $on can help on this.

As you can see if you use $scope.$emit it will fire an event up to the $scope and since that, if you use $scope.$broadcast will fire the event down.

Finally using $scope.$on is how you will listen for these events.

As you can understand better with the next example:

// firing an event upwards
$scope.$emit('myCustomEvent', 'Data to send');

// firing an event downwards
$scope.$broadcast('myCustomEvent', {
  someProp: 'Sending you an Object!' // send whatever you want
});

// listen for the event in the relevant $scope
$scope.$on('myCustomEvent', function (event, data) {
  console.log(data); // 'Data to send'
});
Francisco Maria Calisto
  • 2,841
  • 4
  • 22
  • 54
  • 1
    `angular.bootstrap()` has nothing to do with bootstrap.js. – charlietfl Aug 29 '15 at 21:45
  • 1
    you still have references to bootstrap.js in this question, even after the edits, but this question has nothing to do with that. also, the question doesn't have anything to do with the event system in angular. overall, this answer is solving a different issue, and referring to other frameworks, it's not really an answer to this question. – Claies Aug 30 '15 at 00:10