Javascript AngularJS:指示指令的范围
我正在构建一个可以在不同控制器中使用的指令,并且我希望能够将该指令绑定到我的Javascript AngularJS:指示指令的范围,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我正在构建一个可以在不同控制器中使用的指令,并且我希望能够将该指令绑定到我的$scope的特定属性 我想这样做: <div ng-app="myapp"> <div ng-controller="myController"> <my-directive-wrapper ng-model="mymodel"> <my-directive-inner ng-repeat="item in items" />
$scope
的特定属性
我想这样做:
<div ng-app="myapp">
<div ng-controller="myController">
<my-directive-wrapper ng-model="mymodel">
<my-directive-inner ng-repeat="item in items" />
</my-directive-wrapper>
</div>
</div>
因此指令myDirectiveWrapper
将$scope.mymodel
作为作用域,而没有其他内容。然后我可以把指令放两次,每次指向一个不同的属性
我有一个演示项目,这里有一个问题:
同样的演示在这里正常工作(不限制范围):
问题是,在使用我的指令时,如何表明我希望使用我的$scope
的特定属性作为指令的作用域。应该可以将指令绑定到同一$scope
中的任意属性
干杯。如果您想要双向绑定工作,只需在指令作用域上创建一个变量,而不是直接将
mymodel
应用到指令作用域上,将会容易得多
HTML
<div ng-app="myapp">
<div ng-controller="myController">
<my-directive-wrapper model="mymodel">
<my-directive-inner ng-repeat="item in mymodel.items" />
</my-directive-wrapper>
</div>
</div>
指令
.directive("myDirectiveWrapper", function(){
return {
scope: {
model: '='
},
restrict: 'E',
transclude: true,
link: function(scope, element, attrs, controller) {
},
template: "<div><h3>{{ model.name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
})
指令(“myDirectiveWrapper”,函数(){
返回{
范围:{
型号:'='
},
限制:'E',
是的,
链接:功能(范围、元素、属性、控制器){
},
模板:“{model.name}”
如果您不关心双向绑定,我想您可以这样做,但我不推荐:
.directive("myDirectiveWrapper", function(){
return {
scope: {
model: '='
},
restrict: 'E',
transclude: true,
link: function(scope, element, attrs, controller) {
angular.extend(scope, scope.model);
},
template: "<div><h3>{{ name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
})
指令(“myDirectiveWrapper”,函数(){
返回{
范围:{
型号:'='
},
限制:'E',
是的,
链接:功能(范围、元素、属性、控制器){
角度扩展(范围,范围,模型);
},
模板:“{{name}”
下面是第二种方法可能导致问题的示例。请注意,当您在输入字段中输入某个内容时,它将更改指令的名称,但不会更改外部范围中的名称:因此,这个问题的基本答案是-您可以做您想做的事情,但这比您可能想象的要复杂一些nd此处发生的情况您需要了解angular中的作用域。作用域本质上是一个包含视图可访问数据的对象。作用域在angular中的操作方式(至少)有三种:
- 孤立-在本例中,angular基本上为指令创建了一个全新的范围。没有复制任何属性
- 扩展-在这种情况下,您将从根范围开始,但创建它的浅层副本。更改的对象将在根范围中更改,但原语不会更改
- 共享-在这种情况下,您与根作用域共享部分甚至全部数据
// create a "new" scope
var childScope = scope.$new();
// extend using the model binding provided
angular.extend(childScope, scope[iAttr.myModel]);
在您的指令上下文中,这看起来像:
.directive('myDirectiveWrapper', ['$compile', function ($compile) {
return {
transclude: true,
restrict: 'E',
compile: function (element, attrs, transclude) {
var contents = element.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
var childScope = scope.$new();
angular.extend(childScope, scope[iAttr.myModel]);
if (!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(childScope, function(clone, childScope) {
iElement.append(clone);
});
};
},
template: "<div><h3>{{ name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
}])
.directive('myDirectiveWrapper',['$compile',函数($compile){
返回{
是的,
限制:'E',
编译:函数(元素、属性、转置){
var contents=element.contents().remove();
var编译内容;
返回函数(范围、IELENT、iAttr){
var childScope=scope.$new();
角度扩展(childScope,scope[iAttr.myModel]);
如果(!compiledContents){
compiledContents=$compile(内容,转包);
}
编译内容(childScope,函数(克隆,childScope){
附加(克隆);
});
};
},
模板:“{{name}”
编辑:为了好玩,我为这个指令创建了一个更复杂的用例:
注意-angular site也有一些非常好的资源来更好地理解作用域。你看过传递到link函数参数上的$transclude
函数吗?它允许你传递一个对象作为transclude部分的作用域和一个DOM替换的函数。检查这个线程如何处理@NidhishKrishnan变量名没有被绑定,它应该在屏幕上显示“Transclude test”"。指令使用的是$scope,而不是它的一部分。这是个好主意。@javaCitymy directive wrapper
应该得到部分模型,而不是转包部分。@vtorola:wrapper指令的内容总是
,还是其他内容?当您不能angular.extend时
它将复制mymodel上的所有基元,因此这将破坏双向绑定。@rob你是对的。因此OP需要指定一个特定变量,或者需要使用对象进行双向绑定,而不是基元。不幸的是,无论采用何种方法,都有局限性……你的解决方案也很好,但是@d尽管存在绑定问题,rew_w的解决方案更接近我想要的。
.directive('myDirectiveWrapper', ['$compile', function ($compile) {
return {
transclude: true,
restrict: 'E',
compile: function (element, attrs, transclude) {
var contents = element.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
var childScope = scope.$new();
angular.extend(childScope, scope[iAttr.myModel]);
if (!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(childScope, function(clone, childScope) {
iElement.append(clone);
});
};
},
template: "<div><h3>{{ name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
}])