How to share the $Scope variable from one controller to another with parameters in Angularjs

Asked

Viewed 536 times

1

I have this:

$scope.products = [];

    $http.get('app/components/job/controller/teste.json').success(function (resource) {
        $scope.products  = resource;
});

$scope.getIdJobs = function(getIdJobs) {
    var result = $filter('filter')( $scope.products, {id:getIdJobs})[0];
    console.log(result);
    console.log(getIdJobs);
}

I wanted my second controller to get the $Scope.getIdJobs variable and store it in a variable again. How can I do that?

app.controller("job_detail", ["$scope", "$http", "$location", "$route","$rootScope", "$routeParams", function($scope, $http, $location, $route, $rootScope, $routeParams) {

    //image home
    $rootScope.home = false;

    //change color background in page job
    $scope.isOnCertainPage = function() {
        return $location.path() === "/job";
    };


    $http.get('app/components/job/controller/teste.json').success(function (resource) {
        $scope.products = resource;
        $scope.jobId = $routeParams.jobId;
        //console.log($scope.jobId);
    }); 

    console.log($scope.title, $scope.localidade, $scope.products);

}]);

app js.

app.config(function($routeProvider, RestangularProvider){
    $routeProvider
        .when("/",{
            templateUrl: "app/components/home/views/job_offers.html",
            controller: "employerCtrl"
        })
        .when("/job" , {
            templateUrl: "app/components/job/views/job.html",
            controller: "job"
        })
        .when("/job/:jobId" , {
            templateUrl: "app/components/job/views/jobdetail.html",
            controller: "job_detail" 
        })   
        .otherwise({
            redirectTo: '/'
        });


});
  • See help: http://stackoverflow.com/questions/12008908/angularjs-how-can-i-pass-variables-between-controllers

  • is a good example but as I am using parameters on different pages it gets lost in the middle

  • What do you mean? Your question was to share a variable between controllers, so there’s more going on? If yes, change your question and add this information.

  • I’ve already changed the content

  • I still can’t figure out what it is. Looking at the link @Miguel shared and your question, it solves the problem. What do you understand in your code as a parameter? Where is this parameter?

  • I consider a parameter for example in my app.js. I have job and job/:id and when going to the id page goes with a parameter. I want the information I upload to any topic to go to the corresponding page of that ID

  • So in your controller job_detail you can capture the ID (jobId) and use it on your controller. This would not be intended?

  • I’ve already managed to get the controller to send the information to another controller with the example of Miguel. I’m using an Angularjs ng-click technology when you press the button it stores in a variable. It is possible that this variable when it loads guardes in the variable I created now to send to the 2 controller?

  • Read my answer on that question: http://answall.com/questions/164782/passar-valor-para-service-factory-em-angularjs

  • Have you ever thought of using ui-router to control the page exchange and so receive parameters through the URL?

Show 5 more comments

4 answers

2

A simple solution is to have a Factory that returns the value you need (an object for example): JS:

// Inicializa a aplicação
var myApp = angular.module('myApp', []);

// Cria a factory para acompartilhar o valor da variável
myApp.factory('Fact', function(){
  return { Value: 'Foo' };
});

// 2 Controllers utilizando o mesmo valor
myApp.controller('FirstCtrl', function( $scope, Fact ){
  $scope.Alpha = Value;
});

myApp.controller('SecondCtrl', function( $scope, Fact ){
  $scope.Beta = Value;
});

HTML:

<div ng-controller="FirstCtrl">
    <input type="text" ng-model="Alpha.Value">
    First {{Alpha.Value}}
</div>

<div ng-controller="SecondCtrl">
<input type="text" ng-model="Beta.Value">
    Second {{Beta.Value}}
</div>

Demo: http://jsfiddle.net/o3751yt3/

When applications get bigger, more complex and more difficult to test you may not want to expose the whole object of a Factory this way, but instead give limited access for example via getters and setters:

myApp.service('Data', function(){
var data =
    {
        Value: ''
    };

    return {
        getValue: function () {
            return data.Value;
        },
        setValue: function (Value) {
            data.Value = Value;
        }
    };
});

With this approach, controllers consume service with new values and use $watch to observe changes :

myApp.controller('FirstCtrl', function( $scope, Data ) {

    $scope.Value = '';

    $scope.$watch('Value', function (newValue, oldValue) {
    if (newValue !== oldValue) Data.setValue(newValue);
    });
});

myApp.controller('SecondCtrl', function( $scope, Data ){

    $scope.$watch(function () { return Data.getValue(); }, function (newValue, oldValue) {
        if (newValue !== oldValue) $scope.Value = newValue;
    });
});

HTML:

<div ng-app="myApp">

    <div ng-controller="FirstCtrl">
        <input type="text" ng-model="Value">
        <br>Controller 1 : <strong>{{Value}}</strong>
    </div>
    <hr>
    <div ng-controller="SecondCtrl">
        Controller 2: {{Value}}
    </div>

</div>

Demo: http://jsfiddle.net/b6ekb3om/

  • 1

    Super helpful answer! I liked it a lot and didn’t know how to use $watch. I’m finishing my app and it can change things a lot.

  • The $watch is a very good communication feature between the components of Gularjs, excessive use is not recommended as it activates a series of processes that can increase the resource consumption of your application. Use sparingly.

1

I’m a beginner too but I’ll try to help you by giving you two tips:

  1. There is a $localStorage which stores information and when loaded can be passed from controllers to controllers, much used for Ids.

  2. Another way would be for you to store this $scope.getIdJobs in one service and then use it in other controllers calling it: job_detail.get();

  • It had to do with that as Miguel said above thank you. Now the variable I created needs to save the information of the ng-click variable and is solved. Do you know if this is possible?

  • $localStorage is not native to angular, modules can be downloaded here: https://github.com/gsklee/ngStorage Method 2 is what I describe in my response proposal. The right way is what works, but there is the recommended way too rsrs

0

You can put the products variable in $rootScope, so you can access it from $rootScope anywhere. But I advise you to use ui-router to pass parameters, it is more cohesive and with less chances of you having undesirable replacement variable value problems, or something like.

You must set the parameter in your state:

.state('contacts', {
    url: "/contacts",
    params: {
        param1: null
    },
    templateUrl: 'contacts.html'
})

And you’re gonna spend it that way:

<a ui-sref="contacts({param1: value1})">View Contacts</a>

$state.go('contacts', {param1: value1})
  • It is not good practice to clone values in $rootScope, http://stackoverflow.com/a/35346083

  • That’s what I said @Leonancarvalho, just read carefully: "You can put the products variable in $rootScope", "But I advise you to use ui-router to pass parameters". Power Voce can, but I advised another exit.

0

Good,

In my opinion, it is advisable for you to create a factory for the date, which will be a Objecto, where you can encapsulate the date and their métodos. Then just call the propriedades what you need in the controllers.

Here is the example in this jsfiddle

myApp.factory('myService', function() {
 return {
  data:[{id:1,content:''},{id:2,content:''},{id:3,content:''}, {id:4,content:''},{id:5,content:''},{id:6,content:'Restante Objecto...'},{id:7,content:''},{id:8,content:''},{id:9,content:''},{id:10,content:''}],
  result:{},
  filterById:function(id){

    //Estou a dar declarar o THIS numa variavel porque vou usa-lo dentro do forEach
    var that = this;

    that.data.forEach(function(item){
      if(item.id===id){that.result=item;}
    });
  }
 };
});

In the controller that accesses routerParams flames the method filterById().

function FirstCtrl($scope,myService) {
  var RouterParamsId = 6;
  myService.filterById(RouterParamsId);
  $scope.job = myService.result;
  console.log()
}

In the second controller just declare the result or if necessary you can even filter again with a new id.

function SecondCtrl($scope,myService) {
  $scope.job = myService.result;
}

Thus cleanse the controllers, and all that pertains to that date can be achieved in controllers and directives easily.

Or you’ll have the option of $rootScope, which also works for what you want.

About the routers, I advise you to take a look at the ui-router, a much superior tool in my view.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.