2016-08-22 79 views
2

我已經遇到了我試圖製作的tab/panel指令中的一個問題。我需要能夠爲每個面板提供模板和控制器,既可以作爲HTML中的字符串,也可以作爲要綁定的表達式。例如。我需要能夠調用它像這樣...自定義指令attr綁定不起作用

<tab-panel tab-id="tab1" 
    template="myTemplate.html" 
    controller="AdminController as adminController" 
></tab-panel> 

或類似這樣的

<tab-panel tab-id="tab1" 
    template="{{model.tabTemplate}}" 
    controller="{{model.tabController}}" 
></tab-panel> 

我使用的是NG,如果每個板裏面的內容開啓和關閉和ng-include和ng-controller來加載內容。這是我的指令的簡化測試用例。

// Tab Panel Directive Controller 
.controller('TabPanelCtrl', function(){ 
    // removed for brevity 
}) 

// Tab Panel Directive 
.directive('s4pTabPanel', function($interpolate) { 

    return { 
     restrict: 'E', 
     scope: { 
      id: '@?tabId', 
      template: '@?', 
      controller: '@?', 
     }, 
     controller: 'TabPanelCtrl as tabPanelCtrl', 
     template: getTemplate 
    }; 


    function getTemplate(element, attr) { 


     // removed for brevity 

     // Panel loads template and controller 
     if(attr.template && attr.controller){ 
      return '<tab-panel-inner ng-if="loadContent" ng-include="template" onload="onPanelLoaded()" ng-controller="controller"></tab-panel-inner>'; 
     } 

     // removed for brevity 

    } 

}); 

因此,模板屬性看起來很好,表達式被評估並且結果字符串被插入到ng-include屬性中。然而,NG-控制器屬性不喜歡它由於某種原因,我得到了以下控制檯錯誤...

Error: ng:areq 
Bad Argument 
Argument 'controller' is not a function, got string 

修復此人幫助將真正理解。

編輯:

只是要清楚,對指令的控制器是好的,它的NG控制器=「控制器」,在該指令的模板位,這是造成問題,因爲它沒有得到其中控制器名稱在通過的「@」結合的評估結果

編輯2:

我敢肯定它是與第一個答案了即

AngularJS: dynamically assign controller from ng-repeat

具體該位:

「你的問題是,NG-控制器應指向控制器本身,沒有與控制器的名字只是字符串」

控制器的名稱包含在指令中的作用域變量中,但它是一個字符串,不確定如果我想保持這種動態,它可以是任何其他方式。

+1

在您的指令定義中,嘗試將控制器作爲'controller:'tabPanelCtrl''並且如果您想使用控制器,然後添加'controllerAs:'tabPanelCtrl'' – stevenelberger

+0

這不是那個壞了的位:)請看看指令模板中的ng控制器,您必須向右滾動才能看到。 – jonhobbs

+0

也許嘗試控制器:'=?' – gyc

回答

0

看起來好像你想根據綁定的控制器動態設置控制器。

在你的代碼中,ng-controller綁定到一個字符串「controller」。這與您的作用域綁定中的控制器不同。

// Panel loads template and controller 
     if(attr.template && attr.controller){ 
      return '<tab-panel-inner ng-if="loadContent" ng-include="template" onload="onPanelLoaded()" ng-controller="controller"></tab-panel-inner>'; 
     } 

我認爲你需要做的是:

...ng-controller="' + controller + '" ... 

或本

...ng-controller="' + attr.controller + '" ... 

,讓您正在訪問控制器對象而不是字符串。

+0

不完全。字符串'controller'在指令模板中,所以實際上是指令作用域上的一個值。這並不重要,儘管它對ng-controller不喜歡的任何字符串都進行了評估。如果你傳遞了一些不需要評估的東西(不包含花括號),但如果你這樣做並不好,最後一種方法是有效的。基本上問題是scope.controller需要被評估,但不是一個字符串。對一個實際的控制者來說,這是不可能的 – jonhobbs

+0

我相信我已經找到了一個黑客解決方案,不過我會在上班時發佈一個黑客解決方案。 – jonhobbs

相關問題