Dynamic NG-Controller Name

前端 未结 3 1113
不知归路
不知归路 2020-11-28 11:09

I want to dynamically specify a controller based on a config that we load. Something like this:

相关标签:
3条回答
  • 2020-11-28 11:28

    I'm using it in ng-repeat, so this is improved code for loops and sub objects:

    Template:

    <div class="col-xs6 col-sm-5 col-md-4 col-lg-3" ng-repeat="box in boxes">
    <div ng-include src="'/assets/js/view/box_campaign.html'" ng-dynamic-controller="box.type"></div>
    </div>
    

    Directive:

    mainApp.directive('ngDynamicController', ['$compile', '$parse',function($compile, $parse) {
      return {
          scope: {
              name: '=ngDynamicController'
          },
          restrict: 'A',
          terminal: true,
          priority: 100000,
          link: function(scope, elem, attrs) {
              elem.attr('ng-controller', scope.name);
              elem.removeAttr('ng-dynamic-controller');
    
              $compile(elem)(scope);
          }
      };
    }]);
    
    0 讨论(0)
  • 2020-11-28 11:39

    Personally the 2 current solutions here didn't work for me, as the name of the controller would not be known when first compiling the element but later on during another digest cycle. Therefore I ended up using:

    myapp.directive('dynamicController', ['$controller', function($controller) {
      return {
        restrict: 'A',
        scope: true,
        link: function(scope, elem, attrs) {
          attrs.$observe('dynamicController', function(name) {
            if (name) {
              elem.data('$Controller', $controller(name, {
                $scope: scope,
                $element: elem,
                $attrs: attrs
              }));
            }
          });
        }
      };
    }]);
    
    0 讨论(0)
  • 2020-11-28 11:47

    What you want to do is have another directive run before anything else is called, get the controller name from some model remove the new directive and add the ng-controller directive, then re-compile the element.

    That looks like this:

    global.directive('dynamicCtrl', ['$compile', '$parse',function($compile, $parse) {
      return {
        restrict: 'A',
        terminal: true,
        priority: 100000,
        link: function(scope, elem) {
          var name = $parse(elem.attr('dynamic-ctrl'))(scope);
          elem.removeAttr('dynamic-ctrl');
          elem.attr('ng-controller', name);
          $compile(elem)(scope);
        }
      };
    }]);
    

    Then you could use it in your template, like so:

    <div dynamic-ctrl="'blankCtrl'">{{tyler}}</div>
    

    with a controller like this:

    global.controller('blankCtrl',['$scope',function(tyler){
        tyler.tyler = 'tyler';
        tyler.tyler = 'chameleon';
    }]);
    

    There's probably a way of interpolating the value ($interpolate) of the dynamic-ctrl instead of parsing it ($parse), but I couldn't get it to work for some reason.

    0 讨论(0)
提交回复
热议问题