Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two way binding, shallow $watch, isolate scope not working together

Tags:

angularjs

Please refer to this fiddle for the questions. http://jsfiddle.net/AQR55/

1) Why a watch that is attached to an isolate scope property - which is bidirectionally bound to a parent property, is not triggering on changing the parent scope property.

In the fiddle, the below metioned watch is not getting triggered, on changing the parent scope property to which it is bound.

$scope.$watch('acts', function(neww ,old){
                    console.log(neww)
                })

2) ng-click="addaction()" addaction="addaction()". Can this code be put in more elegant way? Because, to perform an action in isolated scope, it seems we need to set bidirectional binding and the attach to ng-click.

3)Can i declare methods inside the isolated scope like shown below? If i do like this, I'm getting .js error.

<isolate-scope-creating-cmp ng-click="isolateCmpClickHandler()"></isolate-scope-creating-cmp>
scope:{
    isolateCmpClickHandler:function(){
      //If i do like this, I'm getting .js error

    }
}
like image 316
Rajkamal Subramanian Avatar asked Apr 05 '13 04:04

Rajkamal Subramanian


1 Answers

Question 1.
Since you are adding a item to the acts array, you need to set the third parameter in $watch() to true

$scope.$watch('acts', function (neww, old) {
    console.log(neww)
}, true);

Demo: Fiddle

Question 2.
Since there is an isolated scope, you need to call the $parent scope's function

<input type="button" bn="" acts="acts" ng-click="$parent.addaction()" value="Add Action" />

Demo: Fiddle

Question 3.
Yes you can, but you need to use a controller

animateAppModule.directive('bn', function () {
    return {
        restrict: "A",
        scope: {
            acts: '='
        },
        link: function ($scope, iElement, iAttrs) {
            $scope.$watch('acts', function (neww, old) {
                console.log(neww)
            }, true)
        },
        controller: function($scope){
            $scope.dosomething = function(){
                console.log('do something')
            }
        }
    }
})

Demo: Fiddle

An overall solution could look like

<input type="button" bn="" acts="acts" addaction="addaction()" value="Add Action" />

JS

animateAppModule.controller('tst', function ($scope) {
    $scope.acts = [];
    $scope.addaction = function () {
        $scope.acts.push({
            a: "a,b"
        })
    }
})

animateAppModule.directive('bn', function () {
    return {
        restrict: "A",
        scope: {
            acts: '=',
            addaction: '&'
        },
        link: function ($scope, iElement, iAttrs) {
            $scope.$watch('acts', function (neww, old) {
                console.log(neww)
            }, true);
            iElement.click(function(){
                $scope.$apply('addaction()')
            })
        }
    }
})

Demo: Fiddle

like image 92
Arun P Johny Avatar answered Nov 14 '22 04:11

Arun P Johny