1

問題

  • 我有一個項目清單,與ng-repeat建成。
  • 每個項目都有一個帶編輯/刪除項目鏈接的上下文菜單。
  • 上下文菜單是使用像{title: "Link title", href: "/some-href"}這樣的對象陣列中的自定義dropdown-list指令構建的。

我需要通過動態參數ng-hrefproject.id在我的情況),到我的指令的模板,我在ng-repeat使用。我怎樣才能做到這一點?

這是我的一般問題。我覺得我對這裏的Angular JS概念存在重大誤解,並依賴於你的幫助。

我已經試過

我試圖通過字符串數組到我的指令,和我未解析HREF這樣的:

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

這是爲什麼?

項目,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

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

我也試過

傳遞函數解析返回一個字符串數組,但得到的無盡的遞歸錯誤:

10 $digest() iterations reached. Aborting! 

怎麼回事?

項目,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

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

下拉指令代碼

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(); 
      }); 
      } 
     ] 
     }; 
    } 
    ]) 

回答

1

你的第二個方法是比較正確的,因爲你需要構建不同基於上下文的URL。但就像你看到的,你進入了一個無盡的消化週期。

這是因爲你每次

角度把它看作是不同返回不同的數組引用,所以需要曲柄,這再次調用你的函數的另一個反過來,它返回一個新的數組,等等等

您的projectGetContextMenu函數需要緩存結果,並返回相同的引用。就像這樣:

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]; 
}; 
+0

和預期一樣,非常感謝您的快速解決方案!你能否給我一個關於第一種方法的一般性建議?我如何將表達式傳遞給指令的模板?即使在這個特定的情況下,但一般情況下。或者那不是個案,而是誤解? – gkond

+0

第一個解決方案不起作用,因爲您需要每個項目不同的菜單。另一種方法是直接將菜單添加到項目中,然後引用'project.menus' –

相關問題