2015-04-29 147 views
0

我有麻煩找到完全動態指令的解決方案。我使用angular-gridster庫對儀表板頁面的圖塊進行概述。我想通過一個靈活的指令動態加載一些特定的圖塊。動態控制器和templateUrl注入角度指令

<div gridster="vm.model.gridsterOptions"> 

    <ul> 
     <li gridster-item="tile.tileParams.gridParams" ng-repeat="tile in vm.model.dashboards.tiles"> 

      <div class="box" ng-controller="tileGrid_TileController"> 

       <eg-tile template-url={{tile.tileEngine.tempUrl}} 
         controller-name={{tile.tileEngine.tileCtrl}}> 
       </eg-tile> 

      </div> 

     </li> 
    </ul> 

</div> 

我創建了egTile指令:

(function() { 
    function implementation() { 
     return { 
      restrict: 'E', 
      transclude: true, 
      scope: true, 
      controller: '@', 
      bindToController:true, 
      controllerAs: 'vm', 
      name: 'controllerName', 
      templateUrl: function (elem, attrs) { 
       return attrs.templateUrl || 'app/module/tileGrid/view/templates/empty.html'; 
      } 

     }; 
    } 
var declaration = [implementation]; 
angular.module('app.tileGrid').directive('egTile', declaration); 
}()); 

,如果我在egTile指令使用固定字符串像

<eg-tile template-url="string_url" controller-name= "string_ctrl"></eg-tile> 

該指令將工作,但我想要動態選擇控制器和templateUrl。 我已經嘗試使用$ parse和$ observe服務,但沒有成功。 這甚至有可能使指令如此靈活嗎?

在此先感謝

回答

0

我發現我的問題的解決方案.....

我用了2個額外的指令,將提供控制器串和templateUrl字符串爲「靈活的指令」 egTile。

一個用於創建控制器串:

(function() { 
function implementation($compile, $parse) { 
    return { 
     restrict: 'A', 
     scope: true, 
     terminal: true, 
     priority: 99999, 
     link: function (scope, elem) { 
      var name = $parse(elem.attr('eg-parse-controller'))(scope); 
      elem.removeAttr('eg-parse-controller'); 
      elem.attr('controller-name', name); 
      $compile(elem)(scope); 
     } 
    }; 
} 

var declaration = ['$compile', '$parse', implementation]; 
angular.module('app').directive('egParseController', declaration); 

}()); 

和一個用於創建模板字符串:

(function() { 
function implementation($compile, $parse) { 
    return { 
     restrict: 'A', 
     scope: true, 
     terminal: true, 
     priority: 99998, 
     link: function (scope, elem) { 
      var name = $parse(elem.attr('eg-parse-template'))(scope); 
      elem.removeAttr('eg-parse-template'); 
      elem.attr('template-url', name); 
      $compile(elem)(scope); 
     } 
    }; 
} 

var declaration = ['$compile', '$parse', implementation]; 
angular.module('app').directive('egParseTemplate', declaration); 
}()); 

比我可以用它作爲:

<div gridster="vm.model.gridsterOptions"> 

<ul> 
    <li gridster-item="tile.tileParams.gridParams" ng-repeat="tile in vm.model.dashboards.tiles" ng-controller="tileGrid_TileController"> 

     <eg-tile tile="tile" 
       eg-parse-template=tile.tileEngine.tempUrl 
       eg-parse-controller='tile.tileEngine.tileCtrl'> 
     </eg-tile> 
    </li> 
</ul> 

with該指令定義:

(function() { 
function implementation($parse) { 
    return { 
     restrict: 'E', 
     transclude: true, 
     scope: { 
      tile : '=' 
     }, 
     controller: '@', 
     bindToController:true, 
     controllerAs: 'vm', 
     name: 'controllerName', 
     templateUrl: 'app/module/tileGrid/view/tileTemplate.html', 
     link: function(scope, element, attrs) { 
      scope.getContentUrl = function() { 
       return attrs.templateUrl || 'app/module/tileGrid/view/templates/empty.html'; 
      } 
     } 

    }; 
} 

var declaration = ['$parse' , implementation]; 
angular.module('app.tileGrid').directive('egTile', declaration); 
}()); 

隨着tileTemplate.html:

<div class="box"> 

    <div class="box-header"> 
     <h3>{{ vm.tile.tileParams.title }}</h3> 
     <div class="box-header-btns pull-right"> 
      <a title="Remove widget" ng-click="vm.removeTile(tile)"> 
       <i class="fa fa-trash"></i> 
     </a> 
    </div> 

    </div> 
    <div class="box-content"> 
     <div ng-include="getContentUrl()"></div> 
    </div> 
</div> 

有了這個形式給出我已經完全進入我傳遞給egTile指令的動態加載的控制器和動態加載的意見瓷磚。 歡迎所有的評論。