1
app.controller('myCtrl', function($scope, $http) {
    var cy = cytoscape({
  container: document.getElementById('cy') 
   });

    $http({
        method : "GET",
        url : host //Some variable declared, not shown in this example.
    }).then(function mySuccess(response) {
        // Add nodes and edges with data received onto the cytoscape.js graph.
    }, function myError(response) {
        //Error
    });
});

I have an example code written above. I have added nodes and edges upon getting the data through the $http.

I would like to create another controller that will do another $http to a different host and append new nodes/edges to the existing graph.

What is the best way to share the cy variable across controllers to allow the graph to be manipulated?

Additionally, I have noted that I have to code inside the mySuccess scope in order to ensure the graph does not become undefined. This becomes unmanageable and messy. Are there any specific coding conventions I should adopt to circumvent this?

  • So you want something like a global variable? Using the [$rootScope](https://docs.angularjs.org/api/ng/service/$rootScope) is one possibility. – KRONWALLED Jul 12 '16 at 10:13

2 Answers2

1

Angular creates one $scope object for each controller. We also have a $rootScope accesible from every controllers. But, can we access to one controller’s $scope from another controller? The sort answer is no. Also if our application needs to access to another controller’s $scope, we probably are doing something wrong and we need to re-think our problem. But anyway it’s possible to access to another controller’s $scope if we store it within a service

I tried to make a example, hope it will help you to understand. Please change the code according your requirement using $http service

<!doctype html>
<html ng-app="app">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular.js"></script>
    <script src="app.js"></script>
</head>
<body>

<div ng-controller="OneController">
    <h2>OneController</h2>
    <button ng-click="buttonClick()">
        buttonClick on current scope
    </button>
    <button ng-click="buttonClickOnTwoController()">
        buttonClick on TwoController's scope
    </button>
</div>

<div ng-controller="TwoController">
    <h2>TwoController</h2>
    <button ng-click="buttonClick()">
        buttonClick on current scope
    </button>
    <button ng-click="buttonClickOnOneController()">
        buttonClick on OneController's scope
    </button>
</div>
</body>
</html>

and app.js

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

app.run(function ($rootScope) {
    $rootScope.$on('scope.stored', function (event, data) {
        console.log("scope.stored", data);
    });
});
app.controller('OneController', function ($scope, Scopes) {

    Scopes.store('OneController', $scope);

    $scope.variable1 = "One";

    $scope.buttonClick = function () {
        console.log("OneController");
        console.log("OneController::variable1", Scopes.get('OneController').variable1);
        console.log("TwoController::variable1", Scopes.get('TwoController').variable1);
        console.log("$scope::variable1", $scope.variable1);
    };

    $scope.buttonClickOnTwoController = function () {
        Scopes.get('TwoController').buttonClick();
    };
});
app.controller('TwoController', function ($scope, Scopes) {

    Scopes.store('TwoController', $scope);

    $scope.variable1 = "Two";

    $scope.buttonClick = function () {
        console.log("TwoController");
        console.log("OneController::variable1", Scopes.get('OneController').variable1);
        console.log("TwoController::variable1", Scopes.get('TwoController').variable1);
        console.log("$scope::variable1", $scope.variable1);
    };

    $scope.buttonClickOnOneController = function () {
        Scopes.get('OneController').buttonClick();
    };
});
app.factory('Scopes', function ($rootScope) {
    var mem = {};

    return {
        store: function (key, value) {
            $rootScope.$emit('scope.stored', key);
            mem[key] = value;
        },
        get: function (key) {
            return mem[key];
        }
    };
});

You can also see it running here

you can see out put in console

  • I have a unrelated question, I have always use $scope whenever I need to pass data to the front view/html. Do I need to declare normal variables that resist within the controller as $scope.var ? or using var myVar suffice? – Park Taecyeon Jul 12 '16 at 11:15
  • Another question, if accessing the content of another controller is wrong, what kind of coding conventions should I adopt? – Park Taecyeon Jul 12 '16 at 11:16
  • As per your question "What is the best way to share the cy variable across controllers to allow the graph to be manipulated?" you want to share the variable across the controller that's why i have given you a example where you can put the different variable and values from diff controller into single object. – harshal.deshmukh Jul 12 '16 at 11:27
  • Thanks. I would like to also know if I'm using the correct coding convention in angular as I am relatively new to this. I think this would greatly assist in my learning. – Park Taecyeon Jul 13 '16 at 14:27
0

The correct approach would be to wrap the cytoscape object in a service. The service should implement methods for adding/removing edges and other manipulations to the graph. The service can then be injected in any controller (or other service). This has the added benefit to it being an application-wide singleton.

On the details of implementing the service and the difference between angular service, factory and provider you can check this thread.

Community
  • 1
  • 1
kpentchev
  • 3,040
  • 2
  • 24
  • 41