hyperN
hyperN

Reputation: 2754

Angular sharing data between controllers using service

I'm using service to share data between controllers. In first controller I call function like this:

muscleGroupService.setState(true);

Here is code for function in service :

  var state;

  function setState(x) {
        state = x;
    }

x becomes true, but for some reason state doesn't become true, it stays undefined.

How can I fix this ?

Edit

I believe I've managed to find where problem is, but I'm not sure how to solve it.

In Index.html I have this line of code:

<div class="modal fade" ng-include src="'/Content/Templates/Modals/Admin/ModalMuscleGroup.html'"  id="addModal"> </div>

And as soon as I get to page ng-include includes ModalMuscleGroup.html and controller for a modal window.

And I modal widnow controller when I do smth. like this:

muscleGroupService.isItemBeingUpdated()

It returns undefined as I don't watch variable state.

I believe this can be fixes using $rootScope and $rootScope.$broadcast and $rootScope.$on. Is there any other way without using $rootScope ?

Edit 2

Here is code:

Part of Ctrl1 (which should send data to service):

$scope.updateItem = function (item) {
    muscleGroupService.setState(true);
    muscleGroupService.setItemForUpdate(item);
};

Relevat parts of Service:

app.angularModule.service('muscleGroupService', function(breeze, logger) {


    breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);

    var serviceName = "/breeze/MuscleGroup";

    var manager = new breeze.EntityManager(serviceName);

    manager.enableSaveQueuing(true);

    var removeItem = breeze.core.arrayRemoveItem;

    var items = [];
    var state;

    var itemBeingUpdated;


    return {

        setState: function(x) {
            state = x;
        },

        isItemBeingUpdated : function() {
            return state;
        },

        setItemForUpdate : function(item) {
             itemBeingUpdated = item;
        },

        getItemBeingUpdated : function() {
            return itemBeingUpdated;
        },

        updateItem : function() {
            if (itemBeingUpdated.entityAspect.entityState.isModified()) {
                saveChanges();
            }
        },

Here is modal ctrl:

app.angularModule.controller('AdminMuscleGroupModalCtrl', function ($scope, breeze, muscleGroupService) {

    $scope.init = function () {
        if (muscleGroupService.isItemBeingUpdated() == true) {
            $scope.itemBeingUpdated = muscleGroupService.getItemBeingUpdated();  
            $scope.NewName = itemBeingUpdated.Name;
            $scope.NewDesc = itemBeingUpdated.Description;
        }
    };

    $scope.init();
});

Here is part of html for Ctrl1 :

    <tbody>
                        <tr data-ng-repeat="item in items">
                            <td>{{item.Name}}
                            </td>
                            <td>{{item.Description}}
                            </td>
                            <td> <button class="btn btn-primary" data-ng-click="updateItem(item)" data-toggle="modal" href="#addModal"><i class="glyphicon glyphicon-pencil"></i> Edit</button>
     </tr>
                    </tbody>

 <div class="modal fade" ng-include src="'/Content/Templates/Modals/Admin/ModalMuscleGroup.html'"  id="addModal"> </div>

And modal html:

<div class="modal-body">
            <form class="form-horizontal">
                <div class="form-group">
                    <label for="inputName" class="col-lg-2 control-label">Name</label>
                    <div class="col-lg-10">
                        <input type="text" class="form-control" data-ng-model="NewName" id="inputName" placeholder="Name">
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputDesc" class="col-lg-2 control-label">Description</label>
                    <div class="col-lg-10">
                        <input type="text" class="form-control" data-ng-model="NewDesc" id="inputDesc" placeholder="Description">
                    </div>
                </div>
            </form>
        </div>

Upvotes: 0

Views: 1163

Answers (5)

Jon Biere
Jon Biere

Reputation: 31

Services in angular are essentially constructor functions, so behind the scenes where ever you inject your service You get the result of the following call:

new serviceFnc();

Angular will only run it once (singleton) and then give you that object everywhere you've injected the service

so for your example you could do something like this:

myApp.service('muscleGroupService', function(){
//again this function will be newed once
var service = this;

//You dont even need a function just inject muscleGroupService in your controllers and set muscleGroupService.state = true || false
service.state = false;

});

Please see this SO Post for more details on services/factories

Upvotes: 0

hyperN
hyperN

Reputation: 2754

I've managed to solve my problem, this answer helped: link

So I've done something like this:

$scope.$watch( function() { return muscleGroupService.getAction(); }, function() {
        if (muscleGroupService.getAction() == "edit") {
            $scope.$watch(function () { return muscleGroupService.getItemForUpdate(); }, function () {
                $scope.action = "edit";
                $scope.ItemForUpdate = muscleGroupService.getItemForUpdate();
                $scope.NewName = $scope.ItemForUpdate.Name;
                $scope.NewDesc = $scope.ItemForUpdate.Description;
            });
        } else {
            $scope.action = "add";
            $scope.NewName = "";
            $scope.NewDesc = "";
        }
    }); 

Not sure if this is best practice, but it works :)

Upvotes: 0

AlwaysALearner
AlwaysALearner

Reputation: 43947

Try defining your function as below:

myApp.factory('myService', function(){
    var state;
    return {
        setState:function(x){
            state = x;
        }
    }
});

Upvotes: 4

Foo L
Foo L

Reputation: 11137

Have you tried this.state = x?

Upvotes: 0

zs2020
zs2020

Reputation: 54504

Try

this.state = null;
that = this;
function setState(x) {
    that.state = x;
}

Upvotes: 0

Related Questions