2015-04-29 46 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指令的动态加载的控制器和动态加载的意见瓷砖。 欢迎所有的评论。