Javascript 如何将多个值传递给Angularjs指令?

Javascript 如何将多个值传递给Angularjs指令?,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我通过一个指令创建了一个可重用的html。html将有一些我希望从原始范围传递的变量。通过在指令上声明属性,然后创建一个隔离作用域并捕获它们,可以很容易地做到这一点。问题是,有没有更好的方法来处理更多的变量?我曾想过传入一个对象,比如{firstAttr:$scope.one,secondAttr:$scope.two…},然后将这个对象分开,得到每个片段。这是第一次工作,但双向数据绑定不起作用(即使使用“=”) 问题是被绑定的东西是对象,而不是对象的每个单独部分。我可以使用指令中的compil

我通过一个指令创建了一个可重用的html。html将有一些我希望从原始范围传递的变量。通过在指令上声明属性,然后创建一个隔离作用域并捕获它们,可以很容易地做到这一点。问题是,有没有更好的方法来处理更多的变量?我曾想过传入一个对象,比如
{firstAttr:$scope.one,secondAttr:$scope.two…}
,然后将这个对象分开,得到每个片段。这是第一次工作,但双向数据绑定不起作用(即使使用“=”)

问题是被绑定的东西是对象,而不是对象的每个单独部分。我可以使用指令中的compile函数将每个属性添加到元素中吗?因此:

<mydirective databinding="{one:'first one', two:'second one'}">

将转化为:

<mydirective one="first one" two="second one">


这样,通过捕获指令中的属性,我的数据绑定将按预期工作。我该如何完成该设计,或者是否有另一种完全实现该设计的方法?

您可以如下更改指令中的范围

.('mydirective ', function(){

   var linker = function(scope, element){
        console.log(scope.one, scope.two);    
   }    
   return {
        link: linker,
        scope: {one:"=", two:"="}
   }    
});
问题是,有没有更好的方法来处理更多的变量

我不这么认为。正如您已经发现的,尝试将它们作为一个对象传递会导致对象被数据绑定,而不是单个部分

即使您可以使用$compile获得一些东西,阅读您的代码的其他人也不知道发生了什么


另一个选项是不创建作用域(
scope:false
,这是指令的默认设置),或者创建新的子作用域(
scope:true
),但要求调用作用域必须使用特定的作用域属性名才能使用指令。这样就不必指定任何属性。这使得指令的使用更具限制性,但我认为这是您的两个选择:指定多个属性,或要求某些范围属性名称。

数据绑定指令的想法很有趣,但我不会这样做,因为我相信您会遇到指令优先级问题,再加上它是非常非标准的,这将使您的代码很难为未来的程序员所遵循。有几种方法可以做到这一点,所以我将讨论我使用过的3种不同的解决方案

解决方案1

如果您只需要单向数据绑定,最简单的解决方案是在使用{{}插值对象上的任何简单作用域变量后,在指令内对对象的字符串表示形式使用angular的scope.$eval函数。字符串表示甚至不必是有效的JSON,因为在下面的示例中,我没有在对象键周围加引号

他认为:

<div databinding="{one:'first', two:{{scopeVar}}, complex:[1,2, "Hi"]}"></div>
<div databinding="options"></div>
解决方案2

另一种单向数据绑定解决方案是在控制器内创建一个option对象,并使用“@”(甚至“=”)将其传递给指令:

在控制器中:

$scope.options = {one: "first, two: "second"};
$scope.someScopeVar = "Declared in controller"    

$scope.options = {
  dummy: {
     one: $scope.someScopeVar,
     two: "second"
  }
}

window.setTimeout(function(){

  $scope.someScopeVar = "Changed in controller";

}, 2000)
他认为:

<div databinding="{one:'first', two:{{scopeVar}}, complex:[1,2, "Hi"]}"></div>
<div databinding="options"></div>
解决方案3

如果您确实需要双向数据绑定,那么大多数情况下都是运气不佳,因为没有优雅的方法可以做到这一点。但是,如果您正在寻找黑客解决方案,您可以使用与解决方案2非常类似的方法完成双向数据绑定,但需要更改option对象

不要声明包含简单基本数据类型(如字符串)的option对象,而是在option对象内创建一个虚拟对象,然后在其中声明变量。通过这种方式,控制器中范围变量的更改也将在指令内部实现,如超时所示

控制器:

$scope.options = {one: "first, two: "second"};
$scope.someScopeVar = "Declared in controller"    

$scope.options = {
  dummy: {
     one: $scope.someScopeVar,
     two: "second"
  }
}

window.setTimeout(function(){

  $scope.someScopeVar = "Changed in controller";

}, 2000)
视图:


此方法之所以有效,是因为javascript通过引用传递对象,而原语是复制的。通过在对象中嵌套对象,可以保留数据绑定

如果我为每个变量指定了不同的属性,那么这将起作用。我尽量避免这样。我想在一个属性上发送所有数据绑定,然后将它们分开。也许重读这个问题来澄清一下。正是我现在需要的。谢谢大家!@scottmas解决方案2可以与
编译
一起使用,而不是
链接
?遗憾的是,没有,因为编译步骤不是作用域对象。我能想到的在编译时访问选项的唯一方法是,直接在html中将option对象声明为属性,然后只需JSON.parse即可。