如何检查传递给我的Angular指令的属性是表达式还是文字?

时间:2016-05-26 12:25:07

标签: javascript angularjs angularjs-directive

我正在升级遗留应用程序,将大量重复代码转换为Angular 1.5“组件”。

一个重复模式是使用带有ng-click的按钮,该按钮在相关模型上执行任务,我为此创建了一个组件。

然而,这些按钮的传统使用有两种形式。 ng-click是对父作用域中定义的内容的函数引用,有时会向下传递几个组件,例如:

<button ng-click="someScope.deleteFunc">delete</button>

...另一个ng-click是“内联”功能(我的术语可能稍微偏离)。 e.g:

<button ng-click="alert('hello world')">delete</button>

我希望我的组件支持这两种格式,因为重构这些按钮的每次使用都是不可行的,例如:

<special-button click-action="someScope.deleteFunc">Whatever</special-button>
// or
<special-button click-action="alert('hello world')">Whatever</special-button>

我无法解决的问题是如何在我的按钮控制器中支持这些功能。如果我尝试调用$scope.clickAction()()它在第一个实例中工作,但在第二个实例中抛出错误(已成功运行该函数,但这不是重点 - 我希望没有错误。)

是否有某种方法可以解析clickAction是引用还是文字? (我已经调查了$parse,但看不到解决方案)或者我是否以错误的方式行事?或者我没有选择,只要求点击功能以普遍的方式传递?

我以为我能做到:

if(scope.clickAction && typeof scope.clickAction() === "function") {
    // etc
}

...但当然这会在表达式的情况下立即执行clickAction()

更新 这是我的组件代码:

(function (){
'use strict';

angular
    .module('myapp')
    .component('specialButton', {
        templateUrl: 'templates/shared/specialButton/specialButton.html',
        replace: true,
        controller: specialButtonCtrl,
        controllerAs: 'specialbutton',
        bindings: {
            clickAction: '&',
        },
    });

function specialButtonCtrl() {
    var vm = this;

    vm.click = function () {
         vm.clickAction();
    };
}
})(angular);

1 个答案:

答案 0 :(得分:1)

我可能误解了你,但看起来你只需要使用&amp;捆绑。我创建了这个jsfiddle来举例说明。希望能帮助到你! :)

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

app.directive('specialButton',
  function() {
    return {
      restrict: 'E',
      transclude: true,
      template: '<div class="button" ng-click="clickAction()">Call home!</div>',
      controllerAs: 'specialbutton',
      scope: {
        clickAction: '&'
      }
    };
  }
);

app.controller("AppCtrl", function($scope) {
  $scope.callHome = function(message) {
    alert(message);
  };
});
<script src="https://code.angularjs.org/1.0.0/angular-1.0.0.js"></script>
<div ng-app="myApp">
  <div ng-controller="AppCtrl">

    <special-button click-action="callHome('called home!')">
    </special-button>

  </div>
</div>