Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 将$properties添加到转移范围_Angularjs_Transclusion - Fatal编程技术网

Angularjs 将$properties添加到转移范围

Angularjs 将$properties添加到转移范围,angularjs,transclusion,Angularjs,Transclusion,我有一个指令,它的作用域是这样的: <my-control> Some Content: {{value}} </my-control> <my-control> Some Content: {{value}} <button ng-click="$close()">Close</button> </my-control> app.directive('myControl', function()

我有一个指令,它的作用域是这样的:

<my-control>
    Some Content: {{value}}
</my-control>
<my-control>
    Some Content: {{value}}
    <button ng-click="$close()">Close</button>
</my-control>
app.directive('myControl', function() {  
  return {
    restrict: 'E',
    transclude: true,
    controller: function($scope) {
        this.$close = function(){
            //close me
        }
        this.$open = function() {
            //open me
        }

    }
    template: '<div><p><strong>Welcome to the testMe directive!</strong></p> <div transclude-target></div></div>',
    link: function(scope, element, attrs, directiveCtrl, transcludeFn ) {

      transcludeFn(scope.$new(), function (clone, transclusionScope) {
         //only expose the API to the scope if the name attribute is present
          if(attrs.name) {
              transclusionScope[name] = directiveCtrl;
          }
          angular.element(element[0].querySelector('[transclude-target]').append(clone);
      });
    }
  }
});

类似于
ngRepeat
$index
等属性添加到行范围。在我的指令中,最简单的方法是什么?

您可以在指令链接函数中将新方法附加到您的作用域中(如果有,甚至可以在指令的控制器中)

为了简单起见,我将在这里演示如何将新方法附加到指令的链接函数:

app.directive('myControl', function() {
    return {
        restrict: 'E',
        transclude: true,
        template: '<div ng-transclude></div>',
        link: function postLink(scope) {
            scope.$close = function close() {
                console.log("Close function that lives in directive...");
            };
        }
    };
});
<my-control>
    Click <a href ng-click="$close();">close</a> things.
</mycontrol>
app.directive('myControl',function(){
返回{
限制:'E',
是的,
模板:“”,
链接:功能后链接(范围){
作用域$close=函数close(){
log(“关闭指令中的函数…”);
};
}
};
});
在HTML中,您应该能够简单地调用该函数:

app.directive('myControl', function() {
    return {
        restrict: 'E',
        transclude: true,
        template: '<div ng-transclude></div>',
        link: function postLink(scope) {
            scope.$close = function close() {
                console.log("Close function that lives in directive...");
            };
        }
    };
});
<my-control>
    Click <a href ng-click="$close();">close</a> things.
</mycontrol>

点击物品。
还可以使用上面的示例来检查此plunker的实际操作:


我希望这有帮助,如果我遗漏了什么,请随时告诉我,我将很高兴包含任何其他信息。

当我们不指定
范围:true
(新范围)或
范围:{}
(isolatedScope)时,当我们重新使用该指令时,范围上定义的属性将被覆盖

例如:

<div ng-controller="AppCtrl">
    <my-control name="myControl1">
        Some Content: {{value}} 
        My Control Name: {{name}}
    </my-control>
    <my-control name="myControl2">
        Some Content: {{value}} 
        My Control Name: {{name}}
    </my-control>
</div>
在这里,
ng transclude
div下的元素将与transclusionScope一起编译,获取它并更新其中的属性

解决方案2 手动清除内容,而不是使用
ng transclude

app.directive('myControl', function() {  
  return {
    restrict: 'E',
    transclude: true,
    template: '<div><p><strong>Welcome to the testMe directive!</strong></p> <div transclude-target></div></div>',
    link: function(scope, element, attrs, directiveCtrl, transcludeFn ) {

      var transclusionScope = scope.$new(),
          transclusionTarget = element[0].querySelector('[transclude-target]');

      transclusionScope.name = attrs.name;

      transcludeFn(transclusionScope, function (clone) {
        angular.element(transclusionTarget).append(clone);
      });
    }
  }
});
app.directive('myControl',function(){
返回{
限制:'E',
是的,
模板:“欢迎使用testMe指令!

”, 链接:函数(作用域、元素、属性、directiveCtrl、transcludeFn){ var transclusionScope=scope.$new(), transclusionTarget=元素[0]。查询选择器(“[transclude target]”); transclusionScope.name=attrs.name; transcludeFn(transclusionScope,函数(clone){ 元素(transclusionTarget).append(克隆); }); } } });
在这里,使用
Scope.$new()
创建一个
新范围
扩展指令的范围。并更新其中的属性

解决方案1可能不适用于所有情况。当我们访问
firstChild
时,如果未准备好解决方案1将失败


解决方案2更干净,在所有情况下都有效

Vinay的答案是正确的,但我想给它添加一个转折点,使它更“棱角分明”

公开指令API的“角度”方式是通过控制器。我将遵循ngForm指令使用的模式-

大概是这样的:

<my-control>
    Some Content: {{value}}
</my-control>
<my-control>
    Some Content: {{value}}
    <button ng-click="$close()">Close</button>
</my-control>
app.directive('myControl', function() {  
  return {
    restrict: 'E',
    transclude: true,
    controller: function($scope) {
        this.$close = function(){
            //close me
        }
        this.$open = function() {
            //open me
        }

    }
    template: '<div><p><strong>Welcome to the testMe directive!</strong></p> <div transclude-target></div></div>',
    link: function(scope, element, attrs, directiveCtrl, transcludeFn ) {

      transcludeFn(scope.$new(), function (clone, transclusionScope) {
         //only expose the API to the scope if the name attribute is present
          if(attrs.name) {
              transclusionScope[name] = directiveCtrl;
          }
          angular.element(element[0].querySelector('[transclude-target]').append(clone);
      });
    }
  }
});
app.directive('myControl',function(){
返回{
限制:'E',
是的,
控制器:功能($scope){
这是。$close=function(){
//关上我
}
这是。$open=function(){
//打开我
}
}
模板:“欢迎使用testMe指令!

”, 链接:函数(作用域、元素、属性、directiveCtrl、transcludeFn){ transcludeFn(作用域$new(),函数(克隆,transclusionScope){ //仅当name属性存在时,才向作用域公开API 如果(属性名称){ transclusionScope[name]=directiveCtrl; } 元素(元素[0]。查询选择器(“[transclude target]”)。追加(克隆); }); } } });
使用时:

 <my-control name="myControl2">
    <button ng-click="myControl2.$close()>Close</button>
 </my-control>


嘿,保罗!这对你有用吗?@sergiocruz,我需要指令有一个独立的作用域,请参阅接受的答案。是的……我只想指出,如果你在指令声明中添加
scope:{}
,最终结果是一样的。再加上一点更干净的IMHO:)如果你添加自己的方法,为了与AngularJS惯例保持一致,你应该避免使用“$”前缀。嘿,Steve,尽管我同意,我只是想与Paul的问题保持一致,这样我就不会把他弄糊涂了(他问的是$close方法)。此外,值得一提的是,像angular ui这样的大型库确实会在其服务的前面加上$。只是将其放在那里。这之所以有效,是因为指令没有声明自己的作用域,而是将方法附加到继承的作用域,而继承的作用域将可供指令和转置的内容访问。问题是,这也意味着$close方法在指令范围之外是可访问的。在同一父作用域中包含其中两个指令,$close方法将被覆盖。非常感谢,解决方案2成功了。实际上,我也尝试过类似的方法,但当我只想修改作用域,并且我很确定我做错了时,对DOM的处理似乎有点复杂。我想这确实是正确且唯一的选择。我认为在我的例子中,使用控件的名称将大大增加与父作用域发生冲突的几率。另外,ngRepeat将$index等属性直接添加到作用域中,因此这里有一个“官方”API的例子,它的工作方式正好相反。使用“name”属性的意义在于,它可以让您控制如何将API添加到作用域中-因此,如果发生冲突,您只需更改名称即可。在这种情况下,碰撞的可能性为0%。我也不认为将方法(或属性)直接添加到子范围是“错误的”。我刚刚通过经验发现,我所建议的方法效果很好,特别是如果指令的API有多个方法或属性的话。