需要一些自定义AngularJS标记中的绑定属性示例

Need some examples of binding attributes in custom AngularJS tags

我正在尝试创建类似以下内容的自定义标记:

1
<mytag type="Big" />

其中,type是绑定到组件的属性。以这样的方式设置标签中的文本,如下所示:

1
<label>{{type}}</label>

…(其他组件)

如文档所述,我有一个控制器,它设置默认类型:

1
$scope.type ="Small";

因此,如果使用不带属性类型的标记,仍然可以设置类型。

我尝试使用指令进行绑定:

1
2
3
4
5
6
7
8
9
10
angular.module('TestPage',[])
      .directive('mytag',function() {
          return {
              restrict: 'E',
              templateUrl: 'component.html',
              scope: {
                  type: '='
              }
          }
      });

请注意,我的组件模板(ng app="testpage")中确实有适当的ng app设置。

我的问题是,对类型的绑定似乎并没有实际绑定任何内容。

我已经阅读了有关如何使用指令将变量绑定到组件的文档。根据文档,您可以在一个范围内进行这样的绑定。范围显然可以包含"对象哈希"(无论是什么!)它创建了一个叫做"隔离作用域"的东西。??)。这些范围可以通过以下方式表示"本地属性":

@ or @attr - bind a local scope property to the DOM attribute. The result is always a string
since DOM attributes are strings. If no attr name is specified then the local name and
attribute name are same. Given and widget definition of scope: { localName:'@myAttr' }, then widget scope property localName will reflect the interpolated value of hello {{name}}. As the name attribute changes so will the localName property on the widget scope. The name is read from the parent scope (not component scope).

嗯????所有这些与绑定的正确语法有什么关系?

= or =expression - set up bi-directional binding between a local scope property and the parent
scope property. If no attr name is specified then the local name and attribute name are same.
Given and widget definition of scope: { localModel:'=myAttr' }, then widget scope property localName will reflect the value of parentModel on the parent scope. Any changes to parentModel will be reflected in localModel and any changes in localModel will reflect in parentModel.

请原谅我?这里说什么????

& or &attr - provides a way to execute an expression in the context of the parent scope. If no
attr name is specified then the local name and attribute name are same. Given
and widget definition of scope: { localFn:'increment()' },
then isolate scope property localFn will point to a function wrapper for the increment() expression. Often it's desirable to pass data from the isolate scope via an expression and to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).

现在我完全困惑了!你有小部件标签和一些相关的函数,我必须写IIN才能进行绑定????我只想把一个值绑定到一个标签标签上!

我已经从文档(http://docs.angularjs.org/guide/directive)中复制了上述文本来说明一点:这个文档读起来像以前的Unix文档:对那些已经了解系统的人真的很有用,但对那些试图开发真正专业知识的初学者却没有那么大帮助。所有的教程都展示了如何在AngularJS中执行简单的任务(对于玩具应用程序很好,但对于我想要构建的客户端应用程序却不太好),为什么没有更高级的东西呢????

好吧,是时候让我更有建设性了。

有人能提供一些很好的,简单的例子来说明如何进行本文档如此难以描述的各种绑定吗????示例显示了这些作用域语句和描述(纯英语)的正确语法,以及它们如何返回到要添加到自定义标记的属性????

感谢您的耐心等待,并提前感谢您的帮助。

  • 我写了一篇关于这个的博客:我认为这个主题应该在官方教程中——拥有可重用的组件是一个杀手级的特性。我为此提交了一个请求
  • 你并不孤单面对这些挫折。我当然有这种感觉。对于那些读过这篇文章并有类似感觉的人来说,只是一句鼓励的话:坚持住。我不是一个有棱角的球迷或狂热者,但一旦我越过了驼峰,我真的开始享受用它建造的乐趣。(Unix也是如此!;)


当我第一次进入角度的时候,我也对这个文档有点纠结,但是我会尝试为您澄清一些事情。首先,当使用这个scope属性时,它会创建一个"隔离作用域"。这意味着它不会从父作用域继承任何属性,因此您不必担心作用域内的任何冲突。

现在,@'表示法意味着属性中的计算值将自动绑定到指令的作用域中。因此,将以拥有一个名为foo的属性的作用域结束,该属性包含字符串"bar"。您也可以做一些类似于的事情,然后{{bar}}的评估值将绑定到范围中。由于属性始终是字符串,因此在使用此表示法时,您将始终以作用域中此属性的字符串结束。

"="表示法基本上提供了一种将对象传递到指令中的机制。它总是从指令的父范围中提取这个值,因此这个属性永远不会有{{}}。因此,如果您有,它将把$scope.bar中的任何内容绑定到您的指令范围内foo属性中的指令中。您在您的范围内对foo所做的任何更改将在父范围内的bar中重新选择,反之亦然。

我使用"&;"符号的次数也没有使用其他符号的次数多,所以我不知道它和这两个符号一样多。根据我的理解,它允许您从父范围的上下文计算表达式。因此,如果您有类似于的东西,每当您在指令内调用scope.foo(),它都会在指令的父范围内调用dostuff函数。我相信你还可以做更多的事情,但我对这一切都不太熟悉。也许其他人可以更详细地解释这一点。

如果只在作用域中设置了符号,它将使用与属性相同的名称来绑定到指令作用域。例如:

1
2
3
4
5
scope: {
   foo1: '@',
   foo2: '=',
   foo3: '&'
}

当包含指令时,需要有属性foo1、foo2和foo3。如果要在作用域中使用与属性名称不同的属性,可以在符号后指定该属性。所以,上面的例子是

1
2
3
4
5
scope: {
   foo1: '@bar1',
   foo2: '=bar2',
   foo3: '&bar3'
}

当包含该指令时,需要有bar1、bar2和bar3属性,这些属性将分别绑定在foo1、foo2和foo3属性下的范围内。

我希望这有帮助。请随意提问,以便我澄清我的答案。

  • 谢谢你发这篇文章。现在,我对各种符号及其工作方式有了更深入的了解。这很有帮助。
  • 我想知道为什么很难找到文档说明=是用来传递一个对象的。我刚刚读过的所有文档都说=是用于绑定到模型值的,这是不太一般的。它不需要是模型值-任何表达式都有效。


你离得很近……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
app.directive('mytag',function() {
    return {
        restrict: 'E',
        template: '' +
            '<input ng-model="controltype"/>' +
            '<button ng-click="controlfunc()">Parent Func</button>' +
            '<p>
{{controlval}}
</p>' +
         '',
        scope: {
            /* make typeattribute="whatever" bind two-ways (=)
            $scope.whatever from the parent to $scope.controltype
            on this directive's scope */
            controltype: '=typeattribute',
            /* reference a function from the parent through
               funcattribute="somefunc()" and stick it our
               directive's scope in $scope.controlfunc */
            controlfunc: '&funcattribute',
            /* pass a string value into the directive */
            controlval: '@valattribute'
        },
        controller: function($scope) {                  
        }
    };
});

 
       <!-- your directive -->
       <mytag typeattribute="parenttype" funcattribute="parentFn()" valattribute="Wee, I'm a value"></mytag>
       <!-- write out your scope value -->
       {{parenttype}}
 


  app.controller('ParentCtrl', function($scope){
       $scope.parenttype = 'FOO';
       $scope.parentFn = function() {
           $scope.parenttype += '!!!!';
       }
  });

魔力主要在您的指令定义中的scope:声明中。如果有任何EDOCX1[1]在其中,将"隔离"父级的作用域,这意味着它得到了自己的作用域…如果没有这个,它将使用父级的作用域。魔法的其余部分在作用域的属性中:scope: { 'internalScopeProperty' : '=externalAttributeName' }…其中=表示双向绑定场景。如果您将该=更改为@,您将看到它只允许您将字符串作为属性传递给该指令。&用于从父作用域的上下文执行函数。

希望有帮助。

编辑:这是一个正在工作的PLNKR

  • 谢谢你发这个帖子。示例代码非常有用。不幸的是,我不能复制你的例子。我确实有一些问题:您的指令声明中的空"controller"函数似乎没有做任何事情。它与app.controller中声明的函数相关吗?还有:应用程序声明的具体内容是什么?我使用angular.module()声明了该指令。你对"应用"使用类似的说法吗?
  • 应用程序将是你的模块…var app = angular.module('myApp', []);…抱歉,它是主模块的标准变量名。
  • 空的controller函数是该指令的控制器。或者…template中的内容的控制器。
  • 您的指令中的controller部分中的$scope是特定于该指令的范围,它是在指令声明的scope参数中定义的范围。`
  • 抱歉,天哪,我对javascript变量一无所知。我的专长是爪哇、C++和C语言编程。我不是javascript专家。我也做了一些actionscript编程,但是actionscript比javascript更"完整"…无论如何,感谢您的澄清。一个问题:为了使用AngularJS,你必须是JavaScript专家吗?我非常擅长jquery,不必知道javascript的内部结构。对于安古拉基来说,这是真的吗?还是一个真正的javascript专家才能很好地使用它?
  • 一般来说,要进行客户端开发,最好获得一些JavaScript方面的专业知识。我的背景是C语言、Java语言和ActionScript。我向您保证,actionscript并不比javascript更"完整",您可以在javascript中做任何事情,您可以在actionscript中做任何事情,只有更少的关键字。主要要知道的是JavaScript绝对是它自己非常完整、非常有能力的语言,它与C语言或Java非常不同。因此,你不能用Java或C语言来思考JavaScript,你必须用它自己的术语来考虑它。
  • J小提琴不喜欢棱角分明的…使用PLNKR.CO
  • 我已更新了答案,以包含指向工作示例的链接…还有一个打字错误…应该是template而不是templateUrl
  • 知道了。这个例子现在看来有效了。我真的应该注意到打字错误…
  • btw:javascript没有actionscript那么完整,因为尽管它是一种面向对象的语言(实际上是这样),但javascript没有用于类、继承等的语法。这与您可以或不能使用该语言无关。它与语言语法提供的功能有关。
  • 您可以使用JavaScript创建类。您可以将继承与JavaScript结合使用。javascript完成。当你习惯了Java和C语言时,很难理解。我那天也经历过同样的想法。
  • 我没有说你不能用javascript创建类(我一直都这么做!).I说它没有类的语法。这一点本身就使得它不完整。加上缺乏私有、受保护等概念,以及缺乏继承引擎。您可以在javascript中实现继承,甚至可以玩作用域游戏,并使对象中的变量有效地私有化。事实上,你必须实现和玩范围游戏,使语言不完整。一个完整的语言(C++,C语言,Java,Groovy,斯卡拉,露比)不需要这样的努力。javascript不完整。时期。
  • 好。我们不同意。我的回答足以回答你的问题吗?
  • 是的,您的回答是充分的,即使您对"完整的"OO语言有很多了解。JavaScript是否完整不仅仅是一个观点问题。您可以通过提供以下信息来显示它的完整性:1)javascript中的哪个关键字用于声明类?2)哪些javascript关键字声明私有/受保护的变量?3)声明子类的内置语法是什么?这些和其他内置支持使OO语言"完整"。没有它们,任何所谓的OO语言都是不完整的,不管人们的意见如何…