enantiomer2000
enantiomer2000

Reputation: 349

Inject $scope into child model?

I am writing a somewhat complex angularjs application. What I have found is that my main controller model should really consist of several objects that are self contained functions that will be used by other controllers. This would normally not be a problem, but these objects need to be able to tell when a property has been updated. I figured I would pass the $scope into the model object and it could call the $watch function as so:

function MyCtrl($scope){
    $scope.myModel = new MyModel($scope);
    //Do Ctrl Stuff
}

function MyModel($scope){
    $scope.X = 2;
    $scope.Y = 3;
    $scope.$watch('Y', function(oldVal, newVal){
        //do something important
    });
}

When MyCtrl changes the value of $scope.myModel.Y, nothing happens. In fact, it seems that MyModel needs to format its watch like $watch('myModel.Y'... which isn't very useful for abstraction because it would need to know how MyCtrl had assigned it to $scope. I would think that wanting to abstract logic into functions which can be used would be common, but Google searches don't seem to be helping me here. MyModel is actually a decent sized module and I would like to stay as DRY as possible when using it in other controllers. What is the best practice here?

Thanks!

Upvotes: 0

Views: 104

Answers (2)

charlietfl
charlietfl

Reputation: 171669

You should use a service in for this sort of data sharing, what you are doing will get far more complex than needed and angular framework already has the sharing tools you need

Then you can inject the service as dependency in any controller, directive, or other service that needs it

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

app.factory('myDataService',function(){
  return {
    data: {x:2,y:3} ;
     updateData:function( x,y){
          this.data.x=x; 
          this.data.y=y;
     } 
  }
});

app.controller('myCtrl',function($scope, myDataService){
   $scope.data=myDataService.data; 
    $scope.onMyButtonClick=function( x, y){
         myDataService.upDateData(x,y);
    })
});

app.controller('myOtherCtrl',function($scope, myDataService){
  /* when updates made in other controller will automatically be reflected here*/
   $scope.data=myDataService.data
});

Upvotes: 1

Franquis
Franquis

Reputation: 743

Your function MyModel should return $scope if you wanna use it from MyCtrl.

function MyCtrl($scope){
    $scope.myModel = new MyModel($scope);
    //Do Ctrl Stuff
}

function MyModel($scope){
    scope = $scope.$new(); //Creates a new isolated scope
    scope.X = 2;
    scope.Y = 3;
    scope.$watch('Y', function(oldVal, newVal){
        console.log(oldVal, newVal);
    });
    return scope;
}

See this Plunker

Upvotes: 1

Related Questions