具有隔离范围的角度指令,字段不可访问

时间:2015-02-11 17:56:58

标签: angularjs angularjs-directive angularjs-scope

我正在尝试编写一个带有范围变量名的指令,并为其分配将不同的命名参数传递给函数的结果。下面,files="result"旨在在{{result}}隔离范围内创建glob变量。 “matching”变量的内容将在父上下文中进行评估,并分配给隔离的“matching”变量。

该指令然后调用一个函数,最终分配给文件所指向的isolate变量(此处result)返回的数组。然后可以在{{result}}中使用ng-repeat的扩展。

该指令应该可以重用,而无需更改变量名称。

这没有发生。如果我将所有内容分配给父级,我可以使其工作,但每次都需要更改变量名称。

angular.module('j20-glob', ['api'])
/*
 *  usage: <glob files="result" matching="/bin/{{prefix}}*">
 *            {{result}}
 *         </glob>
 *       should allow another just after the first without stomping result
 *      <glob files="result" matching="/something">{{result}}</glob>
 */

.directive('glob', ['$parse', 'api', function($parse, $api) {
  return {
    priority: 99, // it needs to run after the attributes are interpolated    
    restrict: 'AE',
    scope: {

    },

    link: function(scope, iElement, iAttributes) {

       var indexModel = $parse(iAttributes.files);
        iAttributes.$observe('matching', function(value) {
          if (!value)
             return;
          $api.glob(value).then(function(res) {
              indexModel.assign(scope, res);
             // indexModel.assign(scope.$parent, res);
          });
        });
      }
    }
  }
]);

1 个答案:

答案 0 :(得分:0)

如果我在这里理解您的代码,那么您遇到与我在此处回答的问题类似的问题:Directive doesn't work when I which the version of Angular to 1.0.1 to 1.2.27

您已创建了一个名为glob的元素指令。该指令具有隔离范围,您可以在示例中附加属性result。一切正常。问题是,隔离范围中的属性只能在指令中访问;在你的情况下,你试图在指令之外访问它。

元素<glob></glob>是你的指令。此元素可以是其他元素的容器,例如角度表达式{{result}},但这些元素不是指令的一部分,因此不在作用域中。

如果您要包含模板,并将{{result}}放在模板中,您会看到预期的结果。但是,如果更改传入的变量,则此操作将停止。

使用transclude函数的工作指令草案可能类似于:

.directive('glob', ['$parse', 'api', function($parse, $api) {
  return {
    priority: 99, // it needs to run after the attributes are interpolated    
    restrict: 'AE',
    scope: {

    },
    transclude : true,
    link: function(scope, iElement, iAttributes, ctrl, transclude) {

       var indexModel = $parse(iAttributes.files);
        iAttributes.$observe('matching', function(value) {
          if (!value)
             return;
          $api.glob(value).then(function(res) {
              indexModel.assign(scope, res);
             // indexModel.assign(scope.$parent, res);
          });
          //append our scope into the DOM element (clone) instead of $scope
          transclude(scope, function(clone, scope){
              element.append(clone);
          });
        });
      }
    }
  }
]);