@@ -867,8 +867,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
867
867
* @param {string|Object } name Name of the directive in camel-case (i.e. <code>ngBind</code> which
868
868
* will match as <code>ng-bind</code>), or an object map of directives where the keys are the
869
869
* names and the values are the factories.
870
- * @param {Function|Array } directiveFactory An injectable directive factory function. See
871
- * {@link guide/directive} for more info.
870
+ * @param {Function|Array } directiveFactory An injectable directive factory function. See the
871
+ * {@link guide/directive directive guide} and the { @link $compile compile API } for more info.
872
872
* @returns {ng.$compileProvider } Self for chaining.
873
873
*/
874
874
this . directive = function registerDirective ( name , directiveFactory ) {
@@ -915,6 +915,162 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
915
915
return this ;
916
916
} ;
917
917
918
+ /**
919
+ * @ngdoc method
920
+ * @name $compileProvider#component
921
+ * @module ng
922
+ * @param {string } name Name of the component in camel-case (i.e. myComp which will match as my-comp)
923
+ * @param {Object } options Component definition object (a simplified
924
+ * {@link ng.$compile#directive-definition-object directive definition object}),
925
+ * has the following properties (all optional):
926
+ *
927
+ * - `controller` – `{(string|function()=}` – Controller constructor function that should be
928
+ * associated with newly created scope or the name of a {@link ng.$compile#-controller-
929
+ * registered controller} if passed as a string. Empty function by default.
930
+ * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller.
931
+ * If present, the controller will be published to scope under the `controllerAs` name.
932
+ * If not present, this will default to be the same as the component name.
933
+ * - `template` – `{string=|function()=}` – html template as a string or a function that
934
+ * returns an html template as a string which should be used as the contents of this component.
935
+ * Empty string by default.
936
+ *
937
+ * If `template` is a function, then it is {@link auto.$injector#invoke injected} with
938
+ * the following locals:
939
+ *
940
+ * - `$element` - Current element
941
+ * - `$attrs` - Current attributes object for the element
942
+ *
943
+ * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
944
+ * template that should be used as the contents of this component.
945
+ *
946
+ * If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with
947
+ * the following locals:
948
+ *
949
+ * - `$element` - Current element
950
+ * - `$attrs` - Current attributes object for the element
951
+ * - `bindings` – `{object=}` – Define DOM attribute binding to component properties.
952
+ * Component properties are always bound to the component controller and not to the scope.
953
+ * - `transclude` – `{boolean=}` – Whether {@link $compile#transclusion transclusion} is enabled.
954
+ * Enabled by default.
955
+ * - `isolate` – `{boolean=}` – Whether the new scope is isolated. Isolated by default.
956
+ * - `restrict` - `{string=}` - String of subset of {@link ng.$compile#-restrict- EACM} which
957
+ * restricts the component to specific directive declaration style. If omitted, this defaults to 'E'.
958
+ * - `$canActivate` – `{function()=}` – TBD.
959
+ * - `$routeConfig` – `{object=}` – TBD.
960
+ *
961
+ * @returns {ng.$compileProvider } Self for chaining.
962
+ * @description
963
+ * Register a component definition with the compiler. This is short for registering a specific
964
+ * type of directive which represents a self-contained UI component in your application. Component
965
+ * definitions are very simple and do not require the complexity behind defining directives.
966
+ * Component definitions usually consist only of the template and the controller backing it.
967
+ * In order to make the definition easier, components enforce best practices like controllerAs
968
+ * and default behaviors like scope isolation and restriction to elements.
969
+ *
970
+ * Here are a few examples of how you would usually define components:
971
+ *
972
+ * ```js
973
+ * var myMod = angular.module(...);
974
+ * myMod.component('myComp', {
975
+ * template: '<div>My name is {{myComp.name}}</div>',
976
+ * controller: function() {
977
+ * this.name = 'shahar';
978
+ * }
979
+ * });
980
+ *
981
+ * myMod.component('myComp', {
982
+ * template: '<div>My name is {{myComp.name}}</div>',
983
+ * bindings: {name: '@' }
984
+ * });
985
+ *
986
+ * myMod.component('myComp', {
987
+ * templateUrl: 'views/my-comp.html',
988
+ * controller: 'MyCtrl as ctrl',
989
+ * bindings: {name: '@' }
990
+ * });
991
+ *
992
+ * ```
993
+ *
994
+ * <br />
995
+ * Components are also useful as route templates (e.g. when using
996
+ * {@link ngRoute ngRoute}):
997
+ *
998
+ * ```js
999
+ * var myMod = angular.module('myMod', ['ngRoute']);
1000
+ *
1001
+ * myMod.component('home', {
1002
+ * template: '<h1>Home</h1><p>Hello, {{ home.user.name }} !</p>',
1003
+ * controller: function() {
1004
+ * this.user = {name: 'world'};
1005
+ * }
1006
+ * });
1007
+ *
1008
+ * myMod.config(function($routeProvider) {
1009
+ * $routeProvider.when('/', {
1010
+ * template: '<home></home>'
1011
+ * });
1012
+ * });
1013
+ * ```
1014
+ *
1015
+ * <br />
1016
+ * When using {@link ngRoute.$routeProvider $routeProvider}, you can often avoid some
1017
+ * boilerplate, by assigning the resolved dependencies directly on the route scope:
1018
+ *
1019
+ * ```js
1020
+ * var myMod = angular.module('myMod', ['ngRoute']);
1021
+ *
1022
+ * myMod.component('home', {
1023
+ * template: '<h1>Home</h1><p>Hello, {{ home.user.name }} !</p>',
1024
+ * bindings: {user: '='}
1025
+ * });
1026
+ *
1027
+ * myMod.config(function($routeProvider) {
1028
+ * $routeProvider.when('/', {
1029
+ * template: '<home user="$resolve.user"></home>',
1030
+ * resolve: {user: function($http) { return $http.get('...'); }}
1031
+ * });
1032
+ * });
1033
+ * ```
1034
+ *
1035
+ * <br />
1036
+ * See also {@link ng.$compileProvider#directive $compileProvider.directive()}.
1037
+ */
1038
+ this . component = function registerComponent ( name , options ) {
1039
+ function factory ( $injector ) {
1040
+ function makeInjectable ( fn ) {
1041
+ if ( isFunction ( fn ) || Array . isArray ( fn ) ) {
1042
+ return function ( tElement , tAttrs ) {
1043
+ return $injector . invoke ( fn , this , { $element : tElement , $attrs : tAttrs } ) ;
1044
+ } ;
1045
+ } else {
1046
+ return fn ;
1047
+ }
1048
+ }
1049
+
1050
+ var template = ( ! options . template && ! options . templateUrl ? '' : options . template ) ;
1051
+ return {
1052
+ controller : options . controller || function ( ) { } ,
1053
+ controllerAs : identifierForController ( options . controller ) || options . controllerAs || name ,
1054
+ template : makeInjectable ( template ) ,
1055
+ templateUrl : makeInjectable ( options . templateUrl ) ,
1056
+ transclude : options . transclude === undefined ? false : options . transclude ,
1057
+ scope : options . isolate === false ? true : { } ,
1058
+ bindToController : options . bindings || { } ,
1059
+ restrict : options . restrict || 'E'
1060
+ } ;
1061
+ }
1062
+
1063
+ if ( options . $canActivate ) {
1064
+ factory . $canActivate = options . $canActivate ;
1065
+ }
1066
+ if ( options . $routeConfig ) {
1067
+ factory . $routeConfig = options . $routeConfig ;
1068
+ }
1069
+ factory . $inject = [ '$injector' ] ;
1070
+
1071
+ return this . directive ( name , factory ) ;
1072
+ } ;
1073
+
918
1074
919
1075
/**
920
1076
* @ngdoc method
0 commit comments