1

I have a directive with refresh scope. In my case refresh should be an object or a function, so how can i assign this to my directive.

1. First case

<!--HTML-->
<directive 
  refresh="vm.refresh">
</directive>

//JS
scope:{refresh:"="}

2. Second case

<directive 
  refresh="vm.refresh(search)">
</directive>

//JS
scope:{refresh:"&"}

3. My case

<directive 
  refresh="vm.refresh or vm.refresh(search)">
</directive>

//JS - What to do ? need help
scope:{refresh:"=&needHelp"}

But i need this both features in my directive, So how can i isolate this both. I need to know applied refresh scope is object OR function in link function of directive.

6
  • And how refresh is going to be used in case of refresh="vm.refresh"? Commented Feb 20, 2016 at 9:04
  • @dfsq I mentioned in case1 & case2. Refer HTML portion of these cases Commented Feb 20, 2016 at 9:07
  • Probably you should use an attribute for the object and one for the method, not the same. Commented Feb 20, 2016 at 9:22
  • @Michelem This is the question OP's is asking: how to distinguish what was passed into directive. Commented Feb 20, 2016 at 9:23
  • 1
    @Michelem No, it will not work, because with = the first case will result into function that can be called from directive - ok, but the second case will be undefined (because it will be executed during parse phase) - totally not what we want. Commented Feb 20, 2016 at 9:35

3 Answers 3

2

This is tricky situation. In such case you could check for what type of expression refresh attribute holds. However, you need to parse attribute value manually with the help of $parse service.

.directive('directive', function($parse) {
  return {
    scope: {
      // some other bindings, scope is isolated
    },
    template: '<button ng-click="test()">Test</button>',
    link: function(scope, element, attrs) {

      // parse attribute expression (not evaluated yet)
      var callback = $parse(attrs.refresh);

      scope.search = 'Search query';

      scope.test = function() {

        // when needed to refresh: evaluate refresh callback
        var evalled = callback(scope.$parent, {search: scope.search});
        if (typeof evalled == 'function') {
          evaled(scope.search);
        }
      };
    }
  };
})

In case of refresh="vm.refresh(search)" situation callback(scope.$parent, {search: scope.search}) will do the trick. However, if this evaluation returns a function, it means that this is refresh="vm.refresh" case - then it enters the if block and executes this function with necessary parameter.

Demo: http://plnkr.co/edit/4W0SKOzpL5LUP0OAofp5?p=info

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

2 Comments

Excellent. Going to try
Here some problem, If alert in else then second button nt wrking properly. plnkr.co/edit/MYlyfX70qkkNN2zbKKLu?p=preview
1

You can use expression binding to evaluate the scope variable, and use the $attrs object to determine the type. Refer to example below...

JSFiddle: http://jsfiddle.net/g4bft6rL/

JS

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

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            refresh: '&'
        },
        controller: function ($scope, $attrs) {
            $scope.$watch('refresh', function (prev, curr) {
                $scope.text = 'refresh is a ' + getExpressionType($attrs.refresh);
                $scope.value = $scope.refresh();
            });
        },
        template: "result: {{ text }} = {{ value }}"
    };

    function getExpressionType (expression) {
        // naive, but you get the idea
        return expression.slice(-1)[0] === ')' ? 'function' : 'object';
    }
});

function MyCtrl($scope) {
    $scope.refresh = { a: 1 };
    $scope.refreshFn = function what (arg) {
        return {
            value: arg
        };
    };
    $scope.param = 123;
}

HTML

<div ng-controller="MyCtrl">
  <my-directive refresh="refreshFn(param)"></my-directive>
  <my-directive refresh="refresh"></my-directive>
</div>

1 Comment

No, this is not reliable at all and should not be used. Quick example: <my-directive refresh="data = param"></my-directive> will fail while this is refresh="refreshFn(param)" case.
0

You can try something like below, I havent tested this code but just consider the hint/idea.

<directive refresh="refreshFromOuter" search="outerSearchString">" </directive>

refreshFromOuter can be a string or function. in directive controller

 return {
        restrict: 'EA',
        scope: {
            name: '=',
          refresh:'=',
          search:'@'
        }, 
        controller:function($scope){
            console.log($scope);
          if(angular.isFunction($scope.show)){
            alert('is Function');
            $scope.refresh($scope.search || '');
          }
          else{
            alert($scope.refresh + 'as string');
          }
        },
        template: '<div>Some template</div>'
    };

Comments

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.