iwe*_*ein 1053 angularjs angularjs-directive angularjs-scope isolated-scope
我仔细阅读了关于该主题的AngularJS文档,然后使用指令进行了调整.这是小提琴.
以下是一些相关的片段:
来自HTML:
<pane bi-title="title" title="{{title}}">{{text}}</pane>
Run Code Online (Sandbox Code Playgroud)从窗格指令:
scope: { biTitle: '=', title: '@', bar: '=' },
Run Code Online (Sandbox Code Playgroud)我有几件事没有得到:
"{{title}}"
与'@'
和"title"
使用'='
?我找到了另一个显示表达式解决方案的小提琴:http://jsfiddle.net/maxisam/QrCXh/
Mar*_*cok 1146
为什么我必须将"{{title}}"与" @ "和"title"与" = "一起使用?
@将本地/指令范围属性绑定到DOM属性的计算值.如果使用title=title1
or title="title1"
,则DOM属性"title"的值只是字符串title1
.如果使用title="{{title}}"
,DOM属性"title"的值是插值{{title}}
,因此字符串将是父范围属性"title"当前设置的任何值.由于属性值始终是字符串,因此在使用@时,您将始终在指令范围内以此属性的字符串值结束.
=将本地/指令范围属性绑定到父范围属性.因此,使用=,您可以使用父模型/范围属性名称作为DOM属性的值.你不能将{{}}
s用于=.
使用@,您可以执行诸如title="{{title}} and then some"
- {{title}}插值之类的操作,然后将字符串"和它们一些"连接起来.最终的连接字符串是本地/指令范围属性获取的内容.(你不能用=,只做@.)
使用@,attr.$observe('title', function(value) { ... })
如果需要使用link(ing)函数中的值,则需要使用.例如,if(scope.title == "...")
不会像你期望的那样工作.请注意,这意味着您只能异步访问此属性.如果仅使用模板中的值,则不需要使用$ observe().例如,template: '<div>{{title}}</div>'
.
使用=,您不需要使用$ observe.
我是否也可以直接访问父作用域,而无需使用属性装饰我的元素?
是的,但仅限于您不使用隔离范围.从指令中删除此行
scope: { ... }
然后你的指令不会创建一个新的范围.它将使用父范围.然后,您可以直接访问所有父作用域属性.
文档说"通常需要通过表达式将数据从隔离范围传递到父范围",但这似乎也适用于双向绑定.为什么表达路线会更好?
是的,双向绑定允许本地/指令范围和父范围共享数据."表达式绑定"允许指令调用由DOM属性定义的表达式(或函数) - 您还可以将数据作为参数传递给表达式或函数.因此,如果您不需要与父级共享数据 - 您只想调用父作用域中定义的函数 - 您可以使用&语法.
也可以看看
pix*_*its 538
这里有很多伟大的答案,但我想提供有关之间的差异我的角度来看@
,=
和&
结合被证明对我来说非常有用.
所有三种绑定都是通过元素的属性将数据从父作用域传递到指令的独立作用域的方法:
@ binding用于传递字符串.这些字符串支持
{{}}
插值的表达式.例如: .内插表达式根据指令的父作用域进行评估.=绑定用于双向模型绑定.父范围中的模型链接到指令的隔离范围中的模型.对一个模型的更改会影响另一个模型,反之亦然.
& binding用于将方法传递到指令的作用域中,以便可以在指令中调用它.该方法预先绑定到指令的父作用域,并支持参数.例如,如果方法是父作用域中的hello(name),那么为了从指令内部执行方法,必须调用$ scope.hello({name:'world'})
我发现通过较短的描述引用范围绑定更容易记住这些差异:
@
属性字符串绑定=
双向模型绑定&
回调方法绑定符号还使得范围变量在指令实现中的含义更加清晰:
@
串=
模型&
方法为了有用(对我来说反正):
asg*_*oth 64
这=
意味着双向绑定,因此引用一个变量到父范围.这意味着,当您更改指令中的变量时,它也将在父作用域中更改.
@
表示将变量复制(克隆)到指令中.
据我所知,也<pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>
应该工作.bi-title
将收到父范围变量值,该值可在指令中更改.
如果需要在父作用域中更改多个变量,则可以在指令中对父作用域执行函数(或通过服务传递数据).
Jua*_*dez 39
如果您想通过实例了解更多这方面的工作原理.http://jsfiddle.net/juanmendez/k6chmnch/
var app = angular.module('app', []);
app.controller("myController", function ($scope) {
$scope.title = "binding";
});
app.directive("jmFind", function () {
return {
replace: true,
restrict: 'C',
transclude: true,
scope: {
title1: "=",
title2: "@"
},
template: "<div><p>{{title1}} {{title2}}</p></div>"
};
});
Run Code Online (Sandbox Code Playgroud)
geg*_*geg 38
@
得到字符串
=
2路绑定
&
这种行为稍有不同,因为作用域获取了一个返回传入对象的函数.我认为这是必要的,以使其工作.小提琴应该清楚这一点.
这个小提琴应该证明它们是如何工作的.get...
在名称中特别注意范围功能,以期更好地理解我的意思&
Kop*_*lyf 34
指令中可以添加三种范围:
该指令及其父级(它所在的控制器/指令)范围是相同的.因此,对指令中的范围变量所做的任何更改也会反映在父控制器中.您不需要指定它,因为它是默认值.
在这里,如果更改指令内的范围变量,它将不会反映在父范围内,但是如果更改范围变量的属性,则反映在父范围中,因为您实际修改了父范围的范围变量.
例,
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: true,
link: function(element, scope, attrs){
scope.somvar = "new value"; //doesnot reflect in the parent scope
scope.someObj.someProp = "new value"; //reflects as someObj is of parent, we modified that but did not override.
}
};
});
Run Code Online (Sandbox Code Playgroud)
当您创建插件时会发生这种情况,因为这会使指令变为通用,因为它可以放在任何HTML中,并且不受其父作用域的影响.
现在,如果您不希望与父作用域进行任何交互,则只需将作用域指定为空对象即可.喜欢,
scope: {} //this does not interact with the parent scope in any way
Run Code Online (Sandbox Code Playgroud)
大多数情况并非如此,因为我们需要与父作用域进行一些交互,因此我们希望一些值/更改能够通过.出于这个原因,我们使用:
1. "@" ( Text binding / one-way binding )
2. "=" ( Direct model binding / two-way binding )
3. "&" ( Behaviour binding / Method binding )
Run Code Online (Sandbox Code Playgroud)
@表示来自控制器范围的更改将反映在指令范围中,但如果修改指令范围中的值,则控制器范围变量不会受到影响.
@ always总是希望映射属性是表达式.这是非常重要的; 因为要使"@"前缀起作用,我们需要将属性值包装在{{}}中.
=是双向的,因此如果更改指令范围中的变量,控制器范围变量也会受到影响
&用于绑定控制器范围方法,以便在需要时可以从指令中调用它
这里的优点是变量的名称在控制器范围和指令范围内不必相同.
例如,指令范围有一个变量"dirVar",它与控制器范围的变量"contVar"同步.这为指令提供了很多功能和概括,因为一个控制器可以与变量v1同步,而另一个使用相同指令的控制器可以要求dirVar与变量v2同步.
以下是用法示例:
指令和控制器是:
var app = angular.module("app", []);
app.controller("MainCtrl", function( $scope ){
$scope.name = "Harry";
$scope.color = "#333333";
$scope.reverseName = function(){
$scope.name = $scope.name.split("").reverse().join("");
};
$scope.randomColor = function(){
$scope.color = '#'+Math.floor(Math.random()*16777215).toString(16);
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: {
name: "@",
color: "=",
reverse: "&"
},
link: function(element, scope, attrs){
//do something like
$scope.reverse();
//calling the controllers function
}
};
});
Run Code Online (Sandbox Code Playgroud)
和html(注意@和=的不同):
<div my-directive
class="directive"
name="{{name}}"
reverse="reverseName()"
color="color" >
</div>
Run Code Online (Sandbox Code Playgroud)
这是一个博客的链接,很好地描述了它.
oju*_*rni 20
我们可以使用: -
@: - 用于单向数据绑定的字符串值.在某种程度上数据绑定,您只能将范围值传递给指令
=: - 用于双向数据绑定的对象值.在双向数据绑定中,您可以更改指令中的范围值以及html中的范围值.
&: - 用于方法和功能.
在Angular 1.5及以上版本的组件定义中,
有四种不同类型的绑定:
=
双向数据绑定: - 如果我们更改值,它会自动更新<
单向绑定: - 当我们只想从父作用域读取参数而不更新它时.
@
这是针对字符串参数的
&
如果您的组件需要将某些内容输出到其父作用域,则这适用于回调
Rob*_*bin 12
我创建了一个包含Angular代码的HTML文件,演示了它们之间的差异:
<!DOCTYPE html>
<html>
<head>
<title>Angular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myCtrl as VM">
<a my-dir
attr1="VM.sayHi('Juan')" <!-- scope: "=" -->
attr2="VM.sayHi('Juan')" <!-- scope: "@" -->
attr3="VM.sayHi('Juan')" <!-- scope: "&" -->
></a>
</div>
<script>
angular.module("myApp", [])
.controller("myCtrl", [function(){
var vm = this;
vm.sayHi = function(name){
return ("Hey there, " + name);
}
}])
.directive("myDir", [function(){
return {
scope: {
attr1: "=",
attr2: "@",
attr3: "&"
},
link: function(scope){
console.log(scope.attr1); // =, logs "Hey there, Juan"
console.log(scope.attr2); // @, logs "VM.sayHi('Juan')"
console.log(scope.attr3); // &, logs "function (a){return h(c,a)}"
console.log(scope.attr3()); // &, logs "Hey there, Juan"
}
}
}]);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
该=方式是2路的结合,它可以让你有活你的指令内的变化.当某人将该变量更改为指令时,您将在指令中更改数据,但@ way不是双向绑定.它像Text一样工作.你绑定一次,你将只有它的价值.
为了更清楚地了解它,你可以使用这篇伟大的文章:
这个问题已经被打死了,但是无论如何我都会分享这个问题,以防其他人在AngularJS范围的可怕混乱中挣扎。这将包括=
,<
,@
,&
和::
。完整的文章可以在这里找到。
=
建立双向绑定。更改父级中的属性将导致子级中的更改,反之亦然。
<
建立单向绑定,父母对孩子。更改父级属性将导致子级更改,但是更改子级属性不会影响父级属性。
@
会将标签属性的字符串值分配给子属性。如果该属性包含一个表达式,则该子属性会在表达式计算为其他字符串时更新。例如:
<child-component description="The movie title is {{$ctrl.movie.title}}" />
Run Code Online (Sandbox Code Playgroud)
bindings: {
description: '@',
}
Run Code Online (Sandbox Code Playgroud)
此处,description
子范围内的属性将是expression的当前值"The movie title is {{$ctrl.movie.title}}"
,其中movie
父范围内的对象是。
&
有点棘手,实际上似乎没有令人信服的理由去使用它。它允许您在父作用域中评估表达式,用子作用域中的变量替换参数。一个例子(plunk):
<child-component
foo = "myVar + $ctrl.parentVar + myOtherVar"
</child-component>
Run Code Online (Sandbox Code Playgroud)
angular.module('heroApp').component('childComponent', {
template: "<div>{{ $ctrl.parentFoo({myVar:5, myOtherVar:'xyz'}) }}</div>",
bindings: {
parentFoo: '&foo'
}
});
Run Code Online (Sandbox Code Playgroud)
给定parentVar=10
,表达式parentFoo({myVar:5, myOtherVar:'xyz'})
将计算为5 + 10 + 'xyz'
,并且组件将呈现为:
<div>15xyz</div>
Run Code Online (Sandbox Code Playgroud)
您什么时候想使用这种复杂的功能?&
人们经常使用它来将父范围内的回调函数传递给子范围。但是,实际上,通过使用'<'传递函数可以实现相同的效果,该效果更直接,并且避免了笨拙的花括号语法传递参数({myVar:5, myOtherVar:'xyz'}
)。考虑:
回调使用&
:
<child-component parent-foo="$ctrl.foo(bar)"/>
Run Code Online (Sandbox Code Playgroud)
angular.module('heroApp').component('childComponent', {
template: '<button ng-click="$ctrl.parentFoo({bar:'xyz'})">Call foo in parent</button>',
bindings: {
parentFoo: '&'
}
});
Run Code Online (Sandbox Code Playgroud)
回调使用<
:
<child-component parent-foo="$ctrl.foo"/>
Run Code Online (Sandbox Code Playgroud)
angular.module('heroApp').component('childComponent', {
template: '<button ng-click="$ctrl.parentFoo('xyz')">Call foo in parent</button>',
bindings: {
parentFoo: '<'
}
});
Run Code Online (Sandbox Code Playgroud)
请注意,对象(和数组)是通过引用传递给子作用域的,而不是复制的。这意味着即使是单向绑定,您也在父范围和子范围中使用同一对象。
要查看实际使用的不同前缀,请打开此插头。
一次性绑定(初始化)使用::
[官方文档]
AngularJS的更高版本引入了具有一次性绑定的选项,其中子范围属性仅更新一次。通过消除监视父属性的需求,可以提高性能。语法与上面不同。要声明一次性绑定,请::
在component标签的表达式前面添加:
<child-component
tagline = "::$ctrl.tagline">
</child-component>
Run Code Online (Sandbox Code Playgroud)
这会将值传播tagline
到子作用域,而无需建立单向或双向绑定。注意:如果tagline
最初undefined
位于父作用域中,则angular会一直监视它直到更改为止,然后对子作用域中的相应属性进行一次一次性更新。
下表显示了前缀如何工作,具体取决于属性是对象,数组,字符串等。
归档时间: |
|
查看次数: |
532020 次 |
最近记录: |