简体   繁体   English

如何将$ scope变量传递到自定义指令的字符串模板中?

[英]How can I pass $scope variables into string template of custom directive?

The question 问题

  • I have a list of projects, built with ng-repeat . 我有一个使用ng-repeat构建的项目列表。
  • Each project has a context menu with edit/delete project links. 每个项目都有一个带有编辑/删除项目链接的上下文菜单。
  • Context menus are built with custom dropdown-list directive from the array of objects like {title: "Link title", href: "/some-href"} . 上下文菜单是使用自定义dropdown-list伪指令从诸如{title: "Link title", href: "/some-href"}类的对象数组中构建的。

I need to pass dynamic parameters for ng-href ( project.id in my case), into my directive's template, which I use in ng-repeat . 我需要将ng-href动态参数(本例中为project.id )传递到指令的模板中,该模板在ng-repeat How can I achieve that? 我该如何实现?

That is my general question. 这是我的一般性问题。 I feel like I have significant misunderstanding of Angular JS concepts here and counting on your help. 我觉得我在这里对Angular JS概念有严重的误解,并指望您的帮助。

What I've tried 我尝试过的

I've tried passing array of strings into my directive, and I got unparsed href like this: 我尝试将字符串数组传递到指令中,但无法解析到href如下:

/projects/%7B%7B%20project.id%20%7D%7D/edit

Why is that? 这是为什么?

projects-template.html 项目-template.html

<li ng-repeat="project in data.projects">
    <a ng-href="/projects/{{ project.id }}">{{ project.title }}</a>
    <a dropdown-list="projectContextMenu"></a>

projects.controller.js projects.controller.js

$scope.projectContextMenu = [
    {
      text: "Edit",
      href: "/projects/{{ project.id }}/edit"
    }, {
      text: "Delete",
      href: "/projects/{{ project.id }}/delete"
    }
  ];

I've also tried 我也尝试过

passing a function returning an array of parsed strings, but got an endless recursion error: 传递了一个函数,该函数返回一个已解析的字符串数组,但是遇到了一个无限递归错误:

10 $digest() iterations reached. Aborting!

How come? 怎么会?

projects-template.html 项目-template.html

<li ng-repeat="project in data.projects">
    <a ng-href="/projects/{{ project.id }}">{{ project.title }}</a>
    <a dropdown-list="projectGetContextMenu(project.id)"></a>       

projects.controller.js projects.controller.js

$scope.projectGetContextMenu = function(projectID){
    return [
        {
          text: "Edit",
          href: "/projects/" + projectID + "/edit"
        }, {
          text: "Delete",
          href: "/projects/" + projectID + "/delete"
        }
      ];
}

Dropdown directive code 下拉指令代码

angular.module("ngDropdowns", []).directive("dropdownList", [
    "$compile", "$document", function($compile, $document) {
      var template;
      template =
        "<ul>"+
        "  <li ng-repeat='dropdownItem in dropdownList' ng-class='{ \"active\": dropdownModel && dropdownModel.value == dropdownItem.value }'>"+
        "    <a href='' ng-href='{{ dropdownItem.href }}' ng-click='itemSelect(dropdownItem)'>{{ dropdownItem.text }}</a>"+
        "</ul>";
      return {
        restrict: "A",
        replace: false,
        scope: {
          dropdownList: "=",
          dropdownModel: "="
        },
        controller: [
          "$scope", "$element", "$attrs", function($scope, $element, $attrs) {
            var $template, $wrap;
            $template = angular.element(template);
            $template.data("$dropdownListController", this);
            $element.addClass("dropdown_selected").wrap("<div></div>");
            $wrap = $element.parent();
            $wrap.append($compile($template)($scope));
            $scope.itemSelect = function(dropdownItem) {
              if (dropdownItem.href) {
                return;
              }
              angular.copy(dropdownItem, $scope.dropdownModel);
              $wrap.removeClass("dropdown__active");
            };
            $document.find("body").on("click", function() {
              $wrap.removeClass("dropdown__active");
            });
            $element.on("click", function(event) {
              event.stopPropagation();
              $wrap.toggleClass("dropdown__active");
            });
            $wrap.on("click", function(event) {
              event.stopPropagation();
            });
          }
        ]
      };
    }
  ])

Your second approach is more correct because you need to construct different URLs based on the context. 第二种方法更正确,因为您需要根据上下文构造不同的URL。 But like you saw, you get into an endless digest cycle. 但是就像您看到的那样,您进入了一个无尽的摘要循环。

This is because you are returning a different array reference every time 这是因为您每次都返回不同的数组引用

Angular sees it as being different, so requires another turn of the crank, which calls your function again, which returns a new array, etc, etc. Angular认为它与众不同,因此需要再次转动曲柄,再次调用您的函数,并返回一个新数组,依此类推。

Your projectGetContextMenu function needs to cache the results, and return the same reference. 您的projectGetContextMenu函数需要缓存结果,并返回相同的引用。 Like this: 像这样:

var contextMenus = {};

$scope.projectGetContextMenu = function(projectID){
    if(!contextMenus[projectId]) {

      contextMenus[projectId] = [
        {
          text: "Edit",
          href: "/projects/" + projectID + "/edit"
        }, {
          text: "Delete",
          href: "/projects/" + projectID + "/delete"
        }
      ];
    }

    return contextMenus[projectId];
};

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

相关问题 如何将多个范围变量传递给angularjs中的自定义指令 - how to pass multiple scope variables into custom directive in angularjs Angularjs:如何将范围变量传递给指令? - Angularjs: how to pass scope variables to a directive? 如何将范围变量传递给指令的`tAttrrs`对象? - How can I pass a scope variable into a directive's `tAttrrs` object? 如何在指令外传递&#39;scope&#39;参数 - how can I pass 'scope' argument outside the directive 我该如何将角度为2+的Map从html模板传递到自定义指令? - How can i pass a Map in angular 2+ from html template to custom directive? 将隔离的范围对象传递到角度自定义指令模板中? - Pass in isolated scope object into angular custom directive template? 我如何在angular js模板中传递范围 - How can i pass scope in template in angular js 在自定义指令中,如何在生成模板之前执行逻辑? - In a custom directive, how can I perform logic before generating the template? 如何使用其他自定义指令中的元素标记作为另一个自定义指令的模板 - How can I use the element tags from other custom directive as the template for another custom directive Angular JS:如何在指令本地范围内设置可以在模板中使用的属性? - Angular JS: How do I set a property on directive local scope that i can use in the template?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM