2016-10-27 69 views
1

我確定這個問題之前已經被問過了,但我很難找出正確的東西來搜索。模塊中的AngularJS加載範圍函數

我有許多樣板代碼的應用程序,如paginators,切換,過濾器等。我不想把這些東西變成指令,因爲這看起來像是過度殺傷。目前我正在使用ng-include來幹掉我的HTML,但在我的指令中,我仍然有很多樣板範圍的函數。

我想知道的是如果/如何從模塊加載這些函數,並讓它們自動綁定到範圍。

現在我有這樣的:

.directive('somethingAwesome', ['$http', '$timeout', function($http, $timeout) { 
    return { 
     replace: true, 
     templateUrl: '/assets/awesome_sauce.html', 
     transclude: false, 
     scope: true, 
     controller: ['$scope', '$http', '$timeout', function($scope, $http, $timeout) { 
      // Public Functions List 
      $scope.next = next; 
      $scope.prev = prev; 
      $scope.filter = filter; 
      // ... 

      // Public Functions Definitions 
      function next() { 
       // Do something 
      } 
      function prev() { 
       // Do something 
      } 
      function filter() { 
       // Do something 
      } 
      // ... 
     }] 
    } 
}]) 

我想要做的事更是這樣的:

.directive('somethingAwesome', ['$http', '$timeout', function($http, $timeout) { 
    return { 
     replace: true, 
     templateUrl: '/assets/awesome_sauce.html', 
     transclude: false, 
     scope: true, 
     controller: ['$scope', '$http', '$timeout', function($scope, $http, $timeout) { 
      include boilerplate; 
     }] 
    } 
}]) 

(function boilerplate() { 
    // Public Functions List 
    $scope.next = next; 
    $scope.prev = prev; 
    $scope.filter = filter; 
    // ... 

    // Public Functions Definitions 
    function next() { 
     // Do something 
    } 
    function prev() { 
     // Do something 
    } 
    function filter() { 
     // Do something 
    } 
    // ... 

    return something; 
})() 

這裏的關鍵是,僅僅包括boilerplate結合所有的功能範圍的任何指令或控制器包括它。即使我仍然需要手動將每個函數從boilerplate綁定到作用域,但這樣的作用仍然很有用,因爲它會干擾很多代碼。

這是可能的,如果是這樣,如何?

+0

也許這有助於:http://stackoverflow.com/questions/18378520/angularjs-pass-function-to-directive –

回答

1

另一個,可能更多的角/ OOP這樣做的方式是使用$controller繼承基地/「樣板」控制器。這樣做的好處是讓您對每個控制器使用不同的依賴關係(即如果您的樣板需要$http,但是您的實際控制器不需要,則不需要將$http注入控制器,然後將其傳遞到樣板)。

這是如何擴展控制器的例子(注意,樣板控制器被初始化,則繼承控制器最後,繼承控制器能夠調用$scope.next()):

angular.module('app', []) 
 
.controller('main', function() {}) 
 
.controller('baseController', ['$scope', '$http', '$timeout', function($scope, $http, $timeout) { 
 
    console.log('boilerplate controller init'); 
 
    $scope.next = function() { 
 
    console.log('next called'); 
 
    }; 
 
}]) 
 
.controller('awesomeController', ['$scope', '$controller', function($scope, $controller) { 
 
    $controller('baseController', {$scope: $scope}); 
 
    console.log('awesome controller init'); 
 
    $scope.next(); 
 
}]) 
 
.directive('somethingAwesome', ['$http', '$timeout', function($http, $timeout) { 
 
    return { 
 
     replace: true, 
 
     template: '<p>/assets/awesome_sauce.html</p>', 
 
     transclude: false, 
 
     scope: true, 
 
     controller: 'awesomeController' 
 
    } 
 
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="app" ng-controller="main"> 
 
    <div something-awesome></div> 
 
</div>

+0

這正是我所期待的。謝謝! – ACIDSTEALTH

1

您可以將$ scope傳遞給樣板函數。

.directive('somethingAwesome', ['$http', '$timeout', function($http, $timeout) { 
 
    return { 
 
     replace: true, 
 
     templateUrl: '/assets/awesome_sauce.html', 
 
     transclude: false, 
 
     scope: true, 
 
     controller: ['$scope', '$http', '$timeout', function($scope, $http, $timeout) { 
 
      boilerplate($scope); 
 
     }] 
 
    } 
 
}]) 
 

 
function boilerplate($scope) { 
 
    // Public Functions List 
 
    $scope.next = next; 
 
    $scope.prev = prev; 
 
    $scope.filter = filter; 
 
    // ... 
 

 
    // Public Functions Definitions 
 
    function next() { 
 
     // Do something 
 
    } 
 
    function prev() { 
 
     // Do something 
 
    } 
 
    function filter() { 
 
     // Do something 
 
    } 
 
    // ... 
 

 
    return something; 
 
}

或更多角的方法是創建一個服務/工廠:

.directive('somethingAwesome', ['$http', '$timeout', 'boilerPlate', function($http, $timeout, boilerPlate) { 
 
    return { 
 
     replace: true, 
 
     templateUrl: '/assets/awesome_sauce.html', 
 
     transclude: false, 
 
     scope: true, 
 
     controller: ['$scope', '$http', '$timeout', function($scope, $http, $timeout) { 
 
      boilerplate.setPagination($scope); 
 
     }] 
 
    } 
 
}]) 
 

 
.factory('boilerPlate', [function(){ 
 
    
 
    return { 
 
     setPagination: function($scope){ 
 
     // Public Functions List 
 
     $scope.next = next; 
 
     $scope.prev = prev; 
 
     $scope.filter = filter; 
 
     // ... 
 

 
     // Public Functions Definitions 
 
     function next() { 
 
      // Do something 
 
     } 
 
     function prev() { 
 
      // Do something 
 
     } 
 
     function filter() { 
 
      // Do something 
 
     } 
 
     // ... 
 
     } 
 
    } 
 
}]);

+0

我認爲這是我想要的。去測試它,看看它是如何工作的。 – ACIDSTEALTH

+0

@ACIDSTEALTH我剛更新了它,以便它可以通過角碼編碼約定更好地重複使用。 – Hoyen