如何检查是否已向指令提供表达式属性?

时间:2022-02-18 07:32:56

I've created a directive that accepts a callback as an attribute, e.g:

我创建了一个接受回调作为属性的指令,例如:

<my-directive callback-expression="someFunction()"> </my-directive>

The directive is reusable and hence I've given it an isolate scope. I want to show a button within the directive based on whether that callback-expression attribute is set.

该指令是可重用的,因此我给它一个隔离范围。我想根据是否设置了callback-expression属性在指令中显示一个按钮。

App.directive('myDirective', function(){
  restrict: 'E',
  scope:    {
              callbackExpression: '&'
            },
  template: '<button ng-show="!!callbackExpression">Fire callback</button>'
});

The problem is, it's a function even if the expression is empty:

问题是,即使表达式为空,它也是一个函数:

console.log($scope.callbackExpression) with a blank attribute results in:

具有空白属性的console.log($ scope.callbackExpression)导致:

function (locals) {
  return parentGet(parentScope, locals);
}

My current solution is to have this line at the top of my link function:

我目前的解决方案是将此行放在链接功能的顶部:

if (attributes.callbackExpression) scope.callbackButton = true

Then ng-show on callbackButton

然后在callbackButton上显示ng-show

Are there any alternatives not requiring that extra line & scope property?

有没有其他选择不需要额外的线和范围属性?

2 个解决方案

#1


3  

If you want to avoid putting anything on the stack then you can use the link function where you can access the attributes via attrs. Here are two approaches to that:

如果你想避免在堆栈上放任何东西,那么你可以使用链接功能,你可以通过attrs访问属性。以下是两种方法:

Link function option 1:

链接功能选项1:

Instead of using template, you'd use this link function in your directive which conditionally adds your template:

您可以在指令中使用此链接函数来有条件地添加模板,而不是使用模板:

link: function (scope, element, attrs) {     
     if (attrs.callbackExpression) {
         var html = '<button>Fire callback</button>';
         element.replaceWith(html);
     }
}

Option 1 demo: http://jsfiddle.net/ZC4MZ/2/

选项1演示:http://jsfiddle.net/ZC4MZ/2/

Link function option 2 (better for large templates):

链接功能选项2(适用于大型模板):

For large templates you can use $templateCache. First you add the template:

对于大型模板,您可以使用$ templateCache。首先添加模板:

myApp.run(function($templateCache) {
  $templateCache.put('myDirective.html', '<button>Fire callback</button>');
});

Then use it conditionally just like option 1 but with a $templateCache.get():

然后有条件地使用它,就像选项1,但使用$ templateCache.get():

link: function (scope, element, attrs) {     
    if (attrs.callbackExpression) {
        var html = $templateCache.get('myDirective.html');
        element.replaceWith(html);
    }
}

Making sure to inject $templateCache into your directive:

确保将$ templateCache注入到您的指令中:

myApp.directive('myDirective', function ($templateCache) {

Here's a demo using $templateCache: http://jsfiddle.net/ZC4MZ/3/

这是使用$ templateCache的演示:http://jsfiddle.net/ZC4MZ/3/

Option using just the template:

仅使用模板的选项:

To use the template you'll need a variable on the scope. For this you can keep everything as you have it, just add:

要使用模板,您需要在范围上使用变量。为此,您可以保留所有内容,只需添加:

link: function(scope, element, attrs) {
      scope.callbackExpression = attrs.callbackExpression;}
}

Template/scope variable demo: http://jsfiddle.net/ZC4MZ/5/

模板/范围变量演示:http://jsfiddle.net/ZC4MZ/5/

#2


1  

You can use the $attrs object that you can inject into in your directives to get to this information.

您可以使用可以在指令中注入的$ attrs对象来获取此信息。

Markup:

  <body ng-app="myApp" ng-controller="MyController">
    <my-directive text="No Expression"></my-Directive>
    <my-directive text="Expression" callback-expression="myCallback()"></my-Directive>
  </body>

JS:

app.directive('myDirective', function(){

  return {
    restrict: "E",
    scope: {
      text: '@',
      callbackExpression:'&'
    },
    templateUrl: "partial.html",
    link: function($scope, $elem, $attrs) {
      $scope.expressionCalled = false;
      if ($attrs.callbackExpression) {
        $scope.expressionCalled = true;
      }
    }
  }

});

I created a working plunk for this example: http://plnkr.co/edit/K6HiT2?p=preview

我为这个例子创建了一个工作插件:http://plnkr.co/edit/K6HiT2?p = preview

#1


3  

If you want to avoid putting anything on the stack then you can use the link function where you can access the attributes via attrs. Here are two approaches to that:

如果你想避免在堆栈上放任何东西,那么你可以使用链接功能,你可以通过attrs访问属性。以下是两种方法:

Link function option 1:

链接功能选项1:

Instead of using template, you'd use this link function in your directive which conditionally adds your template:

您可以在指令中使用此链接函数来有条件地添加模板,而不是使用模板:

link: function (scope, element, attrs) {     
     if (attrs.callbackExpression) {
         var html = '<button>Fire callback</button>';
         element.replaceWith(html);
     }
}

Option 1 demo: http://jsfiddle.net/ZC4MZ/2/

选项1演示:http://jsfiddle.net/ZC4MZ/2/

Link function option 2 (better for large templates):

链接功能选项2(适用于大型模板):

For large templates you can use $templateCache. First you add the template:

对于大型模板,您可以使用$ templateCache。首先添加模板:

myApp.run(function($templateCache) {
  $templateCache.put('myDirective.html', '<button>Fire callback</button>');
});

Then use it conditionally just like option 1 but with a $templateCache.get():

然后有条件地使用它,就像选项1,但使用$ templateCache.get():

link: function (scope, element, attrs) {     
    if (attrs.callbackExpression) {
        var html = $templateCache.get('myDirective.html');
        element.replaceWith(html);
    }
}

Making sure to inject $templateCache into your directive:

确保将$ templateCache注入到您的指令中:

myApp.directive('myDirective', function ($templateCache) {

Here's a demo using $templateCache: http://jsfiddle.net/ZC4MZ/3/

这是使用$ templateCache的演示:http://jsfiddle.net/ZC4MZ/3/

Option using just the template:

仅使用模板的选项:

To use the template you'll need a variable on the scope. For this you can keep everything as you have it, just add:

要使用模板,您需要在范围上使用变量。为此,您可以保留所有内容,只需添加:

link: function(scope, element, attrs) {
      scope.callbackExpression = attrs.callbackExpression;}
}

Template/scope variable demo: http://jsfiddle.net/ZC4MZ/5/

模板/范围变量演示:http://jsfiddle.net/ZC4MZ/5/

#2


1  

You can use the $attrs object that you can inject into in your directives to get to this information.

您可以使用可以在指令中注入的$ attrs对象来获取此信息。

Markup:

  <body ng-app="myApp" ng-controller="MyController">
    <my-directive text="No Expression"></my-Directive>
    <my-directive text="Expression" callback-expression="myCallback()"></my-Directive>
  </body>

JS:

app.directive('myDirective', function(){

  return {
    restrict: "E",
    scope: {
      text: '@',
      callbackExpression:'&'
    },
    templateUrl: "partial.html",
    link: function($scope, $elem, $attrs) {
      $scope.expressionCalled = false;
      if ($attrs.callbackExpression) {
        $scope.expressionCalled = true;
      }
    }
  }

});

I created a working plunk for this example: http://plnkr.co/edit/K6HiT2?p=preview

我为这个例子创建了一个工作插件:http://plnkr.co/edit/K6HiT2?p = preview