Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.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 使指令使用父范围?_Angularjs - Fatal编程技术网

Angularjs 使指令使用父范围?

Angularjs 使指令使用父范围?,angularjs,Angularjs,我制定了一个包含指令,如下所示: Log.directive 'logList', () -> return { restrict: 'E' scope: type: '=' templateUrl: "/partials/log" } 我在页面上包含了两次,并且希望两者都使用包含它们的根范围。自从把这个重复的HTML放入一个include之后,我不得不在其中做一些混乱的事情,比如$parent.$p

我制定了一个包含指令,如下所示:

Log.directive 'logList', () ->
    return {
        restrict: 'E'
        scope:
            type: '='
        templateUrl: "/partials/log"
    }
我在页面上包含了两次,并且希望两者都使用包含它们的根范围。自从把这个重复的HTML放入一个include之后,我不得不在其中做一些混乱的事情,比如$parent.$parent.something.

演示:

对于指令,即使它们来自save构造函数,也没有简单的方法自动找到这两个指令的共同作用域。但是您可以在
return
语句之前共享相同的变量

app.directive('logList', function($compile, $templateCache) {

  var sharedScope;

  return {
    restrict: 'E',
    // scope: {
    //   type: '='
    // },
    templateUrl: "log.html",
    link: function(scope, element, attrs) {

      // create shared isolated scope if not defined yet
      if (typeof sharedScope === 'undefined') {
        sharedScope = scope.$new(true);

        // manual bi-directional binding for type attribute
        sharedScope.$watch(function() {
          return scope.$eval(attrs.type);
        }, function(val) {
          sharedScope.type = val;
        });
      }

      // recompile directive DOM content to sharedScope
      var template = $templateCache.get('log.html')[1];
      var newContent = $compile(template)(sharedScope);

      element.html('');
      element.append(newContent);
    }
  };

});
这应该为所有
logList
指令提供一个共享的隔离范围,但是因为您共享一个隔离范围,您只能从首先实例化的指令双向绑定
type
属性。

AngularJS将在指令声明的scope字段中指定任何内容时创建一个隔离的作用域。顾名思义,此隔离作用域不从父作用域继承,因此无法直接访问父作用域值

但是,根据具体情况,有多种方法可以访问父作用域属性,而无需使用容易出错的$parent

例如,通过观察属性本身的值,我们不需要创建一个孤立的作用域,因此我们可以访问所有容器作用域属性:

myApp.controller('MyController', function($scope) {
  $scope.demo = { myValue: "Shared scope value" };
});

myApp.directive('myDirective', function() {

  return {
    template: '<div>{{ demo.myValue }}</div>',
    link: function($scope, $element, $attrs) {
      $attrs.$observe('type', function(value) {
        $element.removeClass();
        $element.addClass('alert alert-' + value);
      });
    }
  };
});
myApp.controller('MyController',函数($scope){
$scope.demo={myValue:“共享范围值”};
});
myApp.directive('myDirective',function(){
返回{
模板:{{demo.myValue}}},
链接:函数($scope、$element、$attrs){
$attrs.$observe('type',函数(值){
$element.removeClass();
$element.addClass('警报-'+值);
});
}
};
});
如果您确实需要双向绑定,它允许您从指令中更新值,那么您可以使用。但在大多数情况下,您不需要此功能,因为您可以访问范围:

myApp.directive('myTwoWayDirective', function() {

  return {
    template: '<div>{{ demo.myValue }}' +
                '<select class="pull-right" ' +
                         'ng-model="demo.twoWayType" ' +
                         'ng-options="type for type in demo.types">' +
                '<select>' +
              '</div>',
    link: function($scope, $element, $attrs) {
      $scope.$watch('demo.twoWayType', function(value) {
        $element.removeClass();
        $element.addClass('alert alert-' + value);
      });
    }
  };
});
myApp.directive('myTwoWayDirective',function(){
返回{
模板:“{demo.myValue}}”+
'' +
'' +
'',
链接:函数($scope、$element、$attrs){
$scope.$watch('demo.twoWayType',函数(值){
$element.removeClass();
$element.addClass('警报-'+值);
});
}
};
});
编辑:

新plunker演示如何 和
一个额外的撞击物可能会提供更多。

这很有效。但我相信它可以做得更好。这让我明白了,包含的行为就像是内联到页面中编写的一样,还可以通过templateReplace参数对其进行一些独特的更改

Log.directive 'logList', ($compile, $templateCache, $http) ->
    return {
        restrict: 'E'
        compile: (element, attr) ->
            return (scope, $element, $attr, ctrl) ->
                $http.get('/partials/log', {cache: $templateCache}).success (template) ->
                    template_replace = if $attr.templatereplace then $attr.templatereplace.split(',') else null
                    angular.forEach template_replace, (value, key) ->
                        template = template.replace '%replace%', value

                    content = $compile(template)(scope)
                    $element.html('')
                    $element.append(content)                
    }
下面是我正在使用的模板的一个示例,只需稍作更改,但在我的应用程序的两列中都是相同的:

div.row(ng-repeat="log in %replace% | prepare_log | orderBy: 'log.created'")
    div.log-wrapper(ng-class="log.level")
        a.pin(title="Pin this log message", ng-click="pin($index, %replace%)")
下面是我实现该指令的主要模板:

div.columns.small-6
    log-list(templateReplace="logs,1")

div.columns.small-6
    log-list(templateReplace="pinned,0")
编辑:

我最终做了什么:

    div.columns.small-6
        div.row(ng-repeat="log in logs | prepare_log | orderBy: 'log.created'", ng-init="pin_or_unpin=1")
            ng-include(src="'/partials/log'")
部分:

div.log-wrapper(ng-class="log.level")
    a.pin(title="Pin this log message", ng-click="pin($index, pin_or_unpin)")

它们实际上包含在同一个控制器中,因此它们已经共享一个父范围。我想做的是让它们“透明”地包含进来,并表现得像我直接将它们放在模板中一样,而不是放在它们自己继承的作用域中。@Joren我刚刚更新了答案,我不知道这是否是您想要的。这看起来可能行得通。我可以用模块的主$scope而不是新的共享作用域来编译指令吗?@Joren,如果您没有在指令上定义
scope
属性,指令将不会创建新的作用域,因此它将与父元素共享作用域。如果您想解释指令的属性值,请使用
var type=$scope.$eval(attrs.type)
对scope上的type属性求值。我想我几乎可以做到这一点,您能详细说明一下$eval吗?这将如何让我向每个指令传递唯一的参数?现在我正在传入一个不同的类型,因此在include中我可以做:div.row(ng repeat=“log in$parent[type]| prepare|log | orderBy:'log.created'”)只需使用attrs参数中的$observe方法,将其值赋给指令的范围,该表达式就会工作。但是(!!)。。。你应该尽量避免使用$parent,当然也没有必要侵入共享范围,在每个链接上编译一个额外的模板,并将该模板与共享范围重新链接:)我将添加一个新的plunker。我对我需要什么和我要求什么的理解随着我查看angular的include source而增加,还有你和黛薇的东西。我想我已经知道我到底需要什么了,但是如果你能给我你对我发布的解决方案的意见,我将不胜感激;它是有效的。。。但是没有必要搜索和替换templatecache并重新编译它。Angular可以以更干净、更高效的方式为您完成所有这些。例如,%replace%占位符可以是作用域中的变量(也可以通过属性提供给指令)。我在答案中添加了一个,也许这会给你更多的洞察力。这个plunker非常棒,它正好说明了我需要什么。事实证明,我让这件事变得比需要的困难得多。当我在include中使用ng repeat时,我失去了作用域,不得不执行$parent、$parent.$parent等操作。当我将ng repeat移到include之外时,一切都很好,让我执行一个简单的ng init来设置include的自定义值。谢谢你帮我度过这段时间。