9

The following controller works without problem.

 app.controller('foo', ['$scope',function ($scope) {
        $scope.delete = function(){
            bar($scope);
         }
    }]);

I tried to make it a little cleaner by using bind:

 app.controller('foo', ['$scope',function ($scope) {
        $scope.delete = bar.bind(null, $scope);
    }]);

Unfortunately, this form does not work as expected and $scope is always supplied with an old version of $scope in bound method (bar here), even after $scope has changed to refer to a different value. What is wrong with it?

What else?

If I should not use bind here, what is the alternative?

11
  • What's inside Util? I can't think on why would you need to do this. Commented Jun 9, 2015 at 12:12
  • 1
    Seems a misuse of bind to me. Commented Jun 9, 2015 at 12:19
  • 1
    Is the problem that a value is being supplied to $scope.delete, but it's an old value? Or is the function just totally failing (or not being supplied a value at all)? Commented Jun 9, 2015 at 12:19
  • @ShawnErquhart What makes you think so? Commented Jun 9, 2015 at 13:01
  • 1
    @PHPst Please modify this post to include an MCVE Commented Jun 15, 2015 at 7:25

5 Answers 5

10

I assume that your problem is that your bound Util.bar is always supplied with an old version of $scope, even after $scope has changed to refer to a different value.

bind binds values, not variables. You are binding the current value of $scope to Util.bar. On the other hand, your first style forces the identifier $scope to be resolved to a value (or, really, outer-scope variable record) every time the function runs.

If $scope changes to refer to a completely different value, you must use the first form. .bind(null, $scope) will resolve $scope to a value immediately and use that value forever, while the first form without bind will resolve $scope to a value every time the function runs.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, What is the alternative method for the second codes.
@PHPst The alternative is what you're already doing in your first example. Can you edit to explain why that is not sufficient?
as @apsillers said in bind $scope gets resolved and gets used in subsequent calls cleaner way is first but still want bind then use this app.controller('foo', ['$scope',function ($scope) { $scope.delete = function(){ bar.bind(null, $scope); } }]);
4

Have a look at this Plunker .

   $scope.delete1 = function(){
      bar($scope);
   };

   $scope.delete2 = bar.bind(null, $scope);

   $scope.delete3 = function(){
      bar(this);
   };

To me it seems to behave exactly as it should: delete1 and delete2 seem to do the same thing on both parent and child controller. Delete 3 behaves differently - the reason is explained very nicely in this answer: controller's scope

Maybe you can specify exactly which behaviour(usecase) you find wrong. The go back links are so that you can leave the controller page and then come back to new instance of controller(and a new scope - as you can see from $scope.$id).

Comments

2

Are you sure bar doesn't use anything from Util? Do this:

app.controller('foo', ['$scope',function ($scope) {
    $scope.delete = Util.bar.bind(Util, $scope);
}]);

Comments

1
+50

As mentioned in apsillers answer above, the bind method is being immediately evaluated upon assignment - so $scope's current value is bound as the argument to pass to the bar function. As far as a 'cleaner' alternative, I don't see why you need something 'cleaner': you're looking to assign $scope.delete as a function that invokes bar with the current $scope value, which your current code does to a T. If you're still searching for something a bit leaner code wise you could always adopt ES6 fat arrow syntax (but you'd need a transpiler like babel)- so your code would look like:

app.controller('foo', ['$scope',function ($scope) {
    $scope.delete = () => bar($scope);
}]);

Comments

-1

as @apsillers said, in bind $scope gets resolved and gets used in subsequent calls,so cleaner way is the first one but still If you want to use bind then use

app.controller('foo', ['$scope',function ($scope) { 
     $scope.delete = function(){ 
         bar.bind(null, $scope); 
     }
}]); 

1 Comment

When delete is called it just creates a function value that is thrown away.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.