简体   繁体   English

AngularJS:ng-repeat在具有隔离范围的自定义指令上

[英]AngularJS : ng-repeat over custom directive with isolate scope

I though that this might be a duplicate of this question , except that I'm not using primitives in my code. 我虽然这可能是这个问题的重复,但是我没有在代码中使用原语。 I have a directive that I'm using to place inline svgs dynamically into my view. 我有一个指令,我正在使用该指令将内嵌svg动态地放置到视图中。 It works like so: 它的工作原理如下:

app.directive('icon', ['$timeout', function($timeout) {
  return {
    restrict: "E",
    scope: {
      href:"@",
      title: "@"
    },
    replace: true,
    templateUrl: $timeout(function(elm,attrs) {
      var definition = {
        add: "add133.svg",
        alert: "warning30.svg",
        attachment: "attachment13.svg",
        call: "auricular6.svg",
        calendar: "calendar5.svg",
        notify: "church2.svg",
        compass: "circular14.svg",
        cloud: "cloud127.svg",
        addUser: "create1.svg",
        delete: "delete30.svg",
        trash: "delete48.svg",
        servicedesk: "edit26.svg",
        email: "email20.svg",
        star: "favourites7.svg",
        key: "key162.svg",
        lock: "lock27.svg",
        search: "magnifier12.svg",
        menu: "menu48.svg",
        print: "printer70.svg",
        settings: "settings21.svg",
        share: "share12.svg",
        customer: "user91.svg"
      };
      return 'svg/' + definition[attrs.name];
    },30000)
  }
}]);

Eventually I'll update the code so that I'm using a service to get the list of definitions from a json file, but I'm only testing this for now. 最终,我将更新代码,以便使用服务从json文件中获取定义列表,但是我现在仅对此进行测试。 This works as expected. 这按预期工作。 But when I repeat over it the value suddenly becomes undefined. 但是当我重复它时,值突然变得不确定。 See my view below: 见下面我的看法:

<div ng-repeat="link in config.mainlinks" ng-class="{true: 'active', false: 'dormant'}[config.urlCheck('{{link.name}}')]" sys-stack="2">
    <a href="{{link.href}}" title="{{link.title}}">
        <icon name="{{link.icon}}"></icon>
    </a>
</div> 

As you might infer from my code, I have a model defined in my controller called config and a property of that model is called mainlinks. 您可能会从我的代码推断出,我在控制器中定义了一个名为config的模型,该模型的一个属性称为mainlinks。 Mainlinks is an object meant to provide the attributes needed for this block of code to work, it looks like this Mainlinks是一个对象,旨在提供此代码块正常工作所需的属性,它看起来像这样

mainlinks: {
        dash: {
          name: "dashbaord",
          href: "#dashboard",
          title: "Dashboard",
          icon: "compass"
        }

When it renders the DOM looks like this: 呈现DOM时,如下所示:

<div ng-repeat="link in config.mainlinks" ng-class="{true: 'active', false: 'dormant'}[config.urlCheck('calendar')]" sys-stack="2" class="ng-scope ng-isolate-scope z2 dormant">
    <a href="#calendar" title="Calendar">
        <icon name="{{link.icon}}"></icon>
    </a>
</div>

But something like this works fine 但是这样的事情很好

<span ng-repeat="link in config.mainlinks">
    {{link.icon}}
</span>

My guess is because my test span and the other working portions of my div block are all on the same scope, that of the controller housing them. 我的猜测是因为我的测试范围和div块的其他工作部分都在同一范围内,即容纳它们的控制器在同一范围内。 But icon has its own isolate scope and on that scope, link.icon has no meaning. 但是icon具有自己的隔离范围,在该范围内,link.icon没有意义。 How can I get around this limitation? 我如何解决这个限制? Or am I completely off base? 还是我完全脱离基地?

The issue is the you can only do so much in the templateUrl function, you atleast need to have static text in the attribute that you can read inside the template url. 问题是您只能在templateUrl函数中做很多事情,您至少需要在模板URL中可以读取的属性中包含静态文本。 If you use interpolated value or scope binding in the attribute it wont be available during the time templateurl is evaluated since the compilation is deferred. 如果您在属性中使用插值或范围绑定,则由于推迟了编译,因此在评估templateurl的过程中将不可用。 since you have everything inside the ng-repeat, your entire ng-repeat and the directive inside will be compile only after the templateurl of your directive is rendered. 由于您在ng-repeat中包含了所有内容,因此整个ng-repeat和其中的指令将仅在呈现指令的templateurl之后才进行编译。 So some options could be instead of template url just place some template and replace it during the linking phase (or postLink phase) of the directive reading the attribute value (since it would be available at that time). 因此,某些选项可以代替模板url,而只需放置一些模板并在读取属性值的指令的链接阶段(或postLink阶段)将其替换(因为那时该属性可用)。 Or just wrap the functionality into a single directive and bind the mainlinks to it. 或者只是将功能包装到单个指令中,然后将主mainlinks绑定到该指令。

Something like this:- 像这样的东西:

markup:- 标记: -

<icons mainlinks="config.mainlinks"></icons>

directive:- 指示:-

.directive('icons', [function() {
  return {
    restrict: "E",
    scope: {
      mainlinks: "="
    },
    templateUrl:'links.html', 
    replace: true,
    link:function(scope, elm, attrs){
    .....

    }
  }
});

Move config.urlCheck and definition could be moved to a service (say svg service) that can be shared (if that is something you use often in your app) and inject it in your directive. 移动config.urlCheckdefinition可以移动到可以共享的服务(例如svg服务)(如果这是您在应用程序中经常使用的东西)并将其注入到指令中。 Also note that mainlinks seems to be dictionary so your ng-repeat should be ng-repeat="(k,link) in mainlinks" 另请注意, mainlinks似乎是字典,因此您的ng-repeat应该是ng-repeat="(k,link) in mainlinks"

Plnkr Plnkr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM