Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.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
Javascript AngularJS:指示指令的范围_Javascript_Angularjs_Angularjs Directive_Angularjs Scope - Fatal编程技术网

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,而不是它的一部分。这是个好主意。@javaCity
my 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>"
    }
}])