7

My question is two fold:

1 - I have a parent state and several child states using ui.router, there's one object (stored in mongodb) that is need in all states, but it gets updated by all states. In this scenario does it make sense to use the parent state's resolve option to populate the object?

2 - If this is the proper way to do this, how can I update that "reference" (the mock service injector created by the ui.router) to that object from every state.

To help in explain he's a example of the idea (lot's of code ommited)

.state('parent',resolve:{objectX:return x.promise;},...);

.controller('childstateCtrl',$scope,objectX){
    $scope.data.objectX = objectX;
    $scope.someEvent =function(){ 
    // something updates objectX on the scope
    }
}

.controller('otherChildCtrl',$scope,objectX){
    // how to get the updated objectX?
}

Thanks in advance

Ricardo Gomes
  • 1,268
  • 2
  • 15
  • 35

2 Answers2

4

Not fully sure if I can see where is the issue... but if you are searching for a way how to share access to updated reference, it should be easy. There is an example

Let's have these states

$stateProvider
  .state('root', {
    abstract: true,
    template: '<div ui-view></div>',
    resolve: {objectX : function() { return {x : 'x', y : 'y'};}},
    controller: 'rootController',
  })
  .state('home', {
    parent: "root",
    url: '/home',
    templateUrl: 'tpl.example.html',
  })
  .state('search', {
    parent: "root",
    url: '/search',
    templateUrl: 'tpl.example.html',
  })
  .state('index', {
    parent: "root", 
    url: '/index',
    templateUrl: 'tpl.example.html',
  })

Working with only one controller (for a root state):

.controller('rootController', function($scope, objectX){
  $scope.data = { objectX: objectX };
})

And for this example, this is shared template:

<div>
  <h3>{{state.current.name}}</3>

  x <input ng-model="data.objectX.x"/>
  y <input ng-model="data.objectX.y"/>
</div>

So, in this scenario, parent (root) has injected an object data into $scope. That reference is then inherit as described here:

Scope Inheritance by View Hierarchy Only

Check that example in action here. If you need more details (than in the link above, check this Q&A)

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • This was it. but a little different, well mostly combining both yours and @Chris T answers. Here's an updated code http://plnkr.co/edit/wFeyMk3FD6kHH1HcRCFa?p=preview. Somehow I thought that since the resolve object was a promise I could not update it. But it seems that it gets "resolved" and the reference is always an object. I know it should be obvious :-) – Ricardo Gomes Oct 07 '14 at 19:46
2

you could store it in a service.

.service("myService", function($q) { 
  // the actual data is stored in a closure variable
  var data = undefined;
  return { 
    getPromise: function() { // promise for some data
      if (data === undefined) // nothing set yet, go fetch it
        return $http.get('resourceurl').then(function(value) { data = value; return data; });
      else
        return $q.when(data); // already set, just wrap in a promise.
    },
    getData: function() { return data; }, // get current data (not wrapped)
    setData: function(newDataVal) { data = newDataVal; } // reset current data
  }
})

// `parent` wont' enter until getPromise() is resolved. 
.state('parent', resolve:{objectX: function(myService) { return myService.getPromise(); } });

.controller('childstateCtrl', $scope, myService) {
    $scope.data.objectX = myService.getData();
    $scope.someEvent = function(someData){ 
      myService.setData(someData);
    }
}

.controller('otherChildCtrl', $scope, myService){
    // how to get the updated objectX?
    var data = myService.getData();
}
Chris T
  • 8,186
  • 2
  • 29
  • 39
  • Hi Chris, your answer is partly what I wanted but the scope inheritance of Radim was just what I was looking for (and also the notion that a resolved promise could be updated [yes dumb one :-)]), so sorry but I'll give the answer to him – Ricardo Gomes Oct 07 '14 at 19:50
  • It should be solved with a .value() so they would share the object through the service, that is the right way, since sharing scopes is not the right way to do it. – Jesú Castillo Jul 11 '17 at 00:06