Javascript 角度指令&;范围问题

Javascript 角度指令&;范围问题,javascript,angularjs,Javascript,Angularjs,我正在使用一个预先存在的模板,试图将其角度化 我有3个指令,基本上是一张卡、一个卡头和一个卡体: <card> <card-header title="My Card"> <input type="text" ng-model="userSearch" /> </card-header> <card-body> <card ng-repeat="item in object

我正在使用一个预先存在的模板,试图将其角度化

我有3个指令,基本上是一张卡、一个卡头和一个卡体:

<card>
    <card-header title="My Card">
        <input type="text" ng-model="userSearch" />
    </card-header>
    <card-body>
        <card ng-repeat="item in object | filter:userSearch">
            <card-body>{{ item.name }}</card-body>
        </card>
    </card-body>
</card>
卡头:

return {
    restrict: 'AE',
    requires: 'card',
    transclude: true,
    replace: true,
    scope: false,
    scope: {
        title: '@',
        secondary: '@',
        theme: '@'
    },
    template: '<div class="card-header" ng-class="theme"><h2 ng-if="title">{{ title }}<small>{{ secondary }}</small></h2><div ng-transclude></div></div>',
}
返回{
限制:“AE”,
要求:'卡',
是的,
替换:正确,
范围:假,
范围:{
标题:“@”,
次要:“@”,
主题:“@”
},
模板:“{{title}}{{secondary}}”,
}
卡体:

return {
    restrict: 'AE',
    requires: '^card',
    transclude: true,
    replace: true,
    scope: false,
    scope: {
        padding: '@',
        theme: '@'
    },
    template: '<div class="card-body" ng-class="theme" ng-transclude></div>',
    link: function($scope, $element, $attributes) {
        if($scope.padding)
            angular.element($element[0]).addClass('card-padding');
    }
}
返回{
限制:“AE”,
需要:“^card”,
是的,
替换:正确,
范围:假,
范围:{
填充:“@”,
主题:“@”
},
模板:“”,
链接:函数($scope、$element、$attributes){
if($scope.padding)
angular.element($element[0]).addClass('card-padding');
}
}

看起来这应该是一个简单的概念,但我不知道当我有自己的范围项,但需要转移并有自己的范围项时,我该如何解决这个问题。

首先,我想你可能有一个标记问题。以下是我认为你的意思:

<card>
    <card-header title="My Card">
        <input type="text" ng-model="userSearch" />
    </card-header>
    <card-body>
        <card ng-repeat="item in object | filter:userSearch">
            <card-body>{{ item.name }}</card-body>
        </card>
    </card-body>  <!--this was card-header, which doesn't make sense -->
</card>
这样做的目的是使转换使用指令作用域,而不是指令作用域(甚至是新作用域)的同级

范围树变为:

<card A>
    <card-header A.(B)>   
        <input A.(B) ng-model="A.(B).userSearch"> 
    </card-header>
    <card-body A.(C)>
        <card A.(C) ng-repeat="A.(C).D.item in A.(C).object | filter: A.(C).userSearch">
              <card-body A.(C).D>{{A.(C).D.item.name}}</card-body>
        </card>
    </card-body>
</card>
Yield是下面的作用域树(现在你的过滤器可以工作了{{item.name}}应该显示正确的版本)


{{A.E.item.name}

我肯定我在某个地方犯了一个错误,但我认为这应该可以解释发生了什么。我希望我的解释更简单,但这是我能做的最好的解释。

这是我对您问题的理解:

如果检查上一条指令,我看到的是模板中没有定义模型

现在,当您指定模板时,它将替换directive元素中的html,这就是模型不出现的原因

也就是说,如果item.name位于卡体指令中,则必须在模板中包含模型

现在,当您使用ng transclude时,它会将原始html放回原处,这就是为什么您能够在某种程度上解决问题(但范围会导致问题)

您必须按如下方式更改模板,并且还必须在隔离范围定义中包含项

template: '<div class="card-body" ng-class="theme">{{item.name}}</div>'
模板:“{{item.name}”
如果您不想修改它并且想使用ng transclude,有两种方法可以从子范围调用父范围变量

  • 改为使用范围对象的属性
  • 因此,与其 itmes为$scope.items您可以改为使用对象并拥有项 as属性:
    $scope.itemModel.items

    现在,如果您修改这些,它们 也将反映在父范围中。由于自然的原因,它的速度更快 javascript的应用

  • 不推荐使用,但您始终可以使用 视图和控制器中的$parent

  • 检查这些是否适合您。

    您可以创建一个plunker吗?卡上有控制器可以吗?子指令可以访问父指令控制器:嗯,我可以这样做,但问题是如果我有卡指令嵌套在彼此之间,我想这也可能导致问题?你为什么要设置
    作用域:false
    然后创建独立的作用域?你确定要考虑什么参数吗?@top.dev不确定,删除它没有任何效果-虽然我现在确实了解问题所在,但想不出如何解决它。哇,谢谢。我完全明白你的意思,我现在已经开始工作了。。。或多或少
    元素.find
    部分无效,但将其替换为
    angular.element(元素[0])。append(克隆)可以。显然,这并不是针对
    transclude target
    位,但我仍然不知道如何针对它。所以现在它只是把它附加到最里面的元素中。我的错。angular.element.find()不支持选择器。我通常将jQuery与angular一起安装。jqLite.find确实支持标记名,所以请尝试将标记更改为find并使用find('translude-target')。啊,很好的一点:)另一件事,如果我尝试向
    ma-card
    )添加范围,它不会加载内部
    ma-card
    指令。如果这是一个完全不同的问题,不要担心哈。当你说“添加范围”时,这是否意味着你将范围设置为true或使用一个独立的范围(范围:{})?啊,设法使用attr.size链接绕过它,将其应用于范围,然后我被排序。谢谢你的帮助。
    template: '<div class="card" transclude-target></div>'
    link: function(scope, element, attr, ctrl, transclude) {
        transclude(scope, function(clone, scope){
             element.find('[transclude-target]').append(clone);
        }
    }
    
    link: function(scope, element, attr, ctrl, transclude) {
        transclude(scope.$parent.$new(), function(clone, scope){
             element.find('[ng-transclude]').append(clone);
        }
    }
    
    <card A>
        <card-header A.(B)>   
            <input A.(B) ng-model="A.(B).userSearch"> 
        </card-header>
        <card-body A.(C)>
            <card A.(C) ng-repeat="A.(C).D.item in A.(C).object | filter: A.(C).userSearch">
                  <card-body A.(C).D>{{A.(C).D.item.name}}</card-body>
            </card>
        </card-body>
    </card>
    
    link: function(scope, element, attr, ctrl, transclude) {
        transclude(scope.$parent, function(clone, scope){
             element.find('[transclude-target]').append(clone);
        }
    }
    
    <card A>
        <card-header A.(B)>   
            <input A ng-model="A.userSearch"> 
        </card-header>
        <card-body A.(C)>
            <card A.E ng-repeat="A.E.item in A.object | filter: A.userSearch">
                 <card-body A.E.(D)>{{A.E.item.name}}
            </card>
        </card-body>
    </card>
    
    template: '<div class="card-body" ng-class="theme">{{item.name}}</div>'