【问题标题】:Angular: function call as attribute value for directiveAngular:函数调用作为指令的属性值
【发布时间】:2016-07-18 14:14:01
【问题描述】:

这是对我的指令的简化:

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    replace: true,
    template:
      '<form name="form" action="{{action}}" method="post" target="_blank">' +
        '<input type="hidden" name="item_name" value="{{itemname}}">' +
      '</form>',
    scope: {
      action: '@action',
      itemname: '@itemname',
    },
    link: function(scope, element, attrs) {
      scope.action = attrs.action || 'http://www.example.com';
      scope.itemname = attrs.itemname();
    }
  };
});

我是这样使用的:

<div ng-if="itemWasSelected">
  <my-directive
     action="{{ 'http://www.example.com' }}"
     itemname="itemNameBuildFunction"
  />
</div>

在我的控制器中,我有:

$scope.itemNameBuildFunction = function() {
  return $scope.value1 + $scope.value2;
};

我希望我的指令在链接时(它位于 ng-if 子句内,因此,我的意思是,当 ng-if 条件评估为真时)调用 attrs.itemname() $scope 函数,分配控制器链接函数中的 scope.itemname 变量。

相反,我得到的是错误:

TypeError: attrs.itemname is not a function

你能给我一些指示吗?如您所见,我对角度指令感到很困惑... :-(

【问题讨论】:

  • 您是否关闭了指令 并尝试了 scope.itemname = attrs.itemname;
  • 这个函数attrs.itemname()是什么?从来没有见过它定义...如果它被定义为函数 attrs 转换为 JSON 对象。所以你必须使用 angular.fromJson(attrs.itemname)
  • @MandeepSingh:首先建议:谢谢,刚刚更正了我的答案;第二个建议:那样,在生成的表单中我得到字符串:itemname,这不是我所期望的...... :-(
  • @Zargold: attrs.itemname 包含一个字符串 (itemNameBuildFunction),它是一个 $scope 函数名...
  • @MandeepSingh:不,不是:我得到了函数名称,而不是评估的函数结果... :-(

标签: javascript angularjs using-directives


【解决方案1】:

你不需要这个声明attrs.itemname()

您在指令中传递的函数引用绑定到scope 上的变量itemname,该变量作为link 函数中的第一个参数传递,isolated scope

只需将语句从

更改
scope.itemname = attrs.itemname();

收件人:

scope.itemname();  // this will call the function `itemNameBuildFunction`

编辑:

您使用了@ 运算符的绑定函数,用于传递原语或对象的情况。您正在传递函数,因此,您应该使用&amp; 运算符,将作为函数进行评估。

scope: {
      action: '@action',
      itemname: '&itemname',
    }

编辑 2: 你应该传递函数itemNameBuildFunction() 而不是itemNameBuildFunction

<my-directive action="{{ 'http://www.example.com' }}" 
    itemname="itemNameBuildFunction()" />

工作Plunker

【讨论】:

  • @Zargold 出了什么问题?你能详细说明或修复它吗?什么是重复的
  • 重复的意思是:别人比你早 2 分钟回答了完全相同的问题。错误的意思:似乎提出问题的人确实有 itemname 的功能,但他没有在正确的地方定义它或者虽然不能确定。
  • scope.itemname() 产生:TypeError: scope.itemname is not a function
  • 男人第一件事,请检查正确的答案和我的。请检查您在那里找到的重复项。第二个attrs.itemname 不会评估为表达式,这就是使用隔离范围的原因。那就是为什么会出现这样的错误
  • 需要一个独立的范围。
【解决方案2】:

在我看来,您实际上想要 '=' 类型,它将接受 javascript 对象并且(不需要 JSON.parse)允许您在您的范围内使用它们。函数是可以使用 (); 运行的 javascript 对象

所以最好的解决方案是: scope: { action: '@', itemname: '=', }, 这将允许您对项目名称进行回调,然后在您认为合适的范围内运行它。

https://plnkr.co/edit/cKzLhP4SwHey266Flr5w?p=preview.

另外,有人会如何提交您提供的表格?如果您想提交隐藏的输入名称,您应该拥有&lt;input type='submit'/&gt; 似乎没有意义。此外,您可能希望使用 templateURL 并包含一个 HTML 模板,而不是在您的 js 中使用一个大的动态表单。

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多