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