2014-07-15 11 views
24

Tôi muốn chỉ định động một bộ điều khiển dựa trên cấu hình mà chúng tôi tải. Một cái gì đó như thế này:Tên NG-Controller động

<div ng-controller="{{config.controllerNameString}}> 
    ... 
</div> 

Làm cách nào để làm điều này trong góc? Tôi nghĩ rằng điều này sẽ rất dễ dàng, nhưng tôi có thể tìm cách để làm điều này.

+0

Có bộ điều khiển gốc hay đây là bộ điều khiển cao nhất không? – tymeJV

+2

nhiều cách tải mẫu dựa trên điều kiện và có bộ điều khiển được đặt trong các mẫu – charlietfl

+0

Điều này sẽ có bộ điều khiển chính. – RonSper

Trả lời

30

Những gì bạn muốn làm là chạy lệnh khác trước khi bất kỳ điều gì khác được gọi, lấy tên bộ điều khiển từ một số mô hình loại bỏ chỉ thị mới và thêm chỉ thị ng-controller, sau đó biên dịch lại phần tử.

Đó trông như thế này:

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

Sau đó, bạn có thể sử dụng nó trong mẫu của bạn, như vậy:

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

với một bộ điều khiển như thế này:

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

Có lẽ một cách nội suy giá trị ($interpolate) của số dynamic-ctrl thay vì phân tích cú pháp ng nó ($parse), nhưng tôi không thể làm cho nó hoạt động vì một lý do nào đó.

+0

Cảm ơn bạn. Chính xác những gì tôi đang tìm kiếm. Trong trường hợp của tôi, tôi muốn chuyển một biến $ scope thay vì một chuỗi. Vì vậy, tôi chỉ cần thực hiện giải pháp Nide-ctrl = "myScopeVariable" – mlhuff12

+6

Nide. Tuy nhiên, tôi đề xuất mức ưu tiên là 550 thay vì 100000. Bằng cách này, chỉ thị được thực hiện trước ng-controller (ưu tiên 600) nhưng SAU nếu-(ưu tiên 600). Nếu không, bạn điều khiển được khởi tạo (trong khi gọi đến $ compile (elem) (scope)) ngay cả khi phần tử không nằm trên trang (nếu ng-if là false). Ngoài ra, bạn có thể truy cập vào các thuộc tính của phần tử bằng cách sử dụng tham số 'attrs' của hàm liên kết để xử lý vỏ lạc đà (ví dụ: attrs.dynamicCtrl). – Marc

5

Tôi đang sử dụng nó trong ng-repeat, vì vậy đây được cải thiện mã cho các vòng lặp và đối tượng phụ:

mẫu:

<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> 

Chỉ thị:

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

thêm: if (scope.src) elem.attr ('src', "'" + scope.src + "'"); để hỗ trợ ng-include –

+0

Bạn đang bao gồm nhà máy '$ parse' nhưng bạn không sử dụng nó. –

+0

nơi cần đặt là: nếu (scope.src) elem.attr ('src', "'" + scope.src + "'"); ? – fancoolo

2

Cá nhân 2 các giải pháp hiện tại ở đây không hiệu quả đối với tôi, vì tên của bộ điều khiển sẽ không được biết khi lần đầu tiên biên dịch phần tử nhưng sau đó trong một chu trình phân tích khác. Do đó tôi đã sử dụng:

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