Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 579a327

Browse files
committed
refactor($mdCompilerProvider): remove deprecated $mdCompilerProvider.respectPreAssignBindingsEnabled()
- remove use of `$controller`'s private and unsupported third argument - this means that locals would only be available in a controller's `$onInit()` - update tests BREAKING CHANGE: The deprecated `$mdCompilerProvider.respectPreAssignBindingsEnabled()` API has been removed. We no longer respect AngularJS's `$compileProvider.preAssignBindingsEnabled()` value as this API was removed in AngularJS `1.7.0`. If you had the recommended configuration for AngularJS 1.6.x: ```js $compileProvider.preAssignBindingsEnabled(false); $mdCompilerProvider.respectPreAssignBindingsEnabled(true); ``` Then you should remove both of these calls as they are now the defaults in AngularJS `1.7.0` and AngularJS Material `1.2.0`. If you had the recommended configuration for AngularJS 1.7+: ```js $mdCompilerProvider.respectPreAssignBindingsEnabled(true); ``` Then you should remove this call as it is now the default in AngularJS Material `1.2.0`. If you were using a backwards-compatible configuration for AngularJS 1.6+: ```js $mdCompilerProvider.respectPreAssignBindingsEnabled(false); ``` Then you will need to remove this call and may need to refactor your Controllers for AngularJS Material components like `$mdDialog`, `$mdPanel`, `$mdToast`, or `$mdBottomSheet`. For example: ```js $mdDialog.show({ locals: { myVar: true }, controller: MyController, bindToController: true } function MyController() { // No locals from Angular Material are available. e.g myVar is undefined. // You would need to move anything accessing locals in here to $onInit(). } MyController.prototype.$onInit = function() { // Bindings are now available in the $onInit lifecycle hook. } ```
1 parent cf3d56c commit 579a327

File tree

2 files changed

+62
-363
lines changed

2 files changed

+62
-363
lines changed

src/core/services/compiler/compiler.js

+13-219
Original file line numberDiff line numberDiff line change
@@ -8,191 +8,8 @@ angular
88
.module('material.core')
99
.provider('$mdCompiler', MdCompilerProvider);
1010

11-
/**
12-
* @ngdoc service
13-
* @name $mdCompilerProvider
14-
* @module material.core.compiler
15-
* @description
16-
* The `$mdCompiler` is able to respect the AngularJS `$compileProvider.preAssignBindingsEnabled`
17-
* state when using AngularJS versions greater than or equal to 1.5.10 and less than 1.7.0.
18-
* See the [AngularJS documentation for `$compileProvider.preAssignBindingsEnabled`
19-
* ](https://code.angularjs.org/1.6.10/docs/api/ng/provider/$compileProvider#preAssignBindingsEnabled)
20-
* for more information.
21-
*
22-
* To enable/disable whether the controllers of dynamic AngularJS Material components
23-
* (i.e. dialog, panel, toast, bottomsheet) respect the AngularJS
24-
* `$compileProvider.preAssignBindingsEnabled` flag, call the AngularJS Material method:
25-
* `$mdCompilerProvider.respectPreAssignBindingsEnabled(boolean)`.
26-
*
27-
* This AngularJS Material *flag* doesn't affect directives/components created via regular
28-
* AngularJS methods. These constitute the majority of AngularJS Material and user-created
29-
* components. Only dynamic construction of elements such as Dialogs, Panels, Toasts, BottomSheets,
30-
* etc. may be affected. Invoking `$mdCompilerProvider.respectPreAssignBindingsEnabled(true)`
31-
* will effect **bindings** in controllers created by AngularJS Material's services like
32-
* `$mdDialog`, `$mdPanel`, `$mdToast`, or `$mdBottomSheet`.
33-
*
34-
* See
35-
* <a ng-href="#mdcompilerprovider-respectpreassignbindingsenabled-respected">
36-
* $mdCompilerProvider.respectPreAssignBindingsEnabled
37-
* </a>
38-
* for the details of how the different versions and settings of AngularJS affect this behavior.
39-
*
40-
* @usage
41-
*
42-
* Respect the AngularJS Compiler Setting
43-
*
44-
* <hljs lang="js">
45-
* app.config(function($mdCompilerProvider) {
46-
* $mdCompilerProvider.respectPreAssignBindingsEnabled(true);
47-
* });
48-
* </hljs>
49-
*
50-
* @example
51-
* Using the default (backwards compatible) values for AngularJS 1.6
52-
* - AngularJS' `$compileProvider.preAssignBindingsEnabled(false)`
53-
* - AngularJS Material's `$mdCompilerProvider.respectPreAssignBindingsEnabled(false)`
54-
* <br><br>
55-
*
56-
* <hljs lang="js">
57-
* $mdDialog.show({
58-
* locals: {
59-
* myVar: true
60-
* },
61-
* controller: MyController,
62-
* bindToController: true
63-
* }
64-
*
65-
* function MyController() {
66-
* // Locals from Angular Material are available. e.g myVar is true.
67-
* }
68-
*
69-
* MyController.prototype.$onInit = function() {
70-
* // Bindings are also available in the $onInit lifecycle hook.
71-
* }
72-
* </hljs>
73-
*
74-
* Recommended Settings for AngularJS 1.6
75-
* - AngularJS' `$compileProvider.preAssignBindingsEnabled(false)`
76-
* - AngularJS Material's `$mdCompilerProvider.respectPreAssignBindingsEnabled(true)`
77-
* <br><br>
78-
*
79-
* <hljs lang="js">
80-
* $mdDialog.show({
81-
* locals: {
82-
* myVar: true
83-
* },
84-
* controller: MyController,
85-
* bindToController: true
86-
* }
87-
*
88-
* function MyController() {
89-
* // No locals from Angular Material are available. e.g myVar is undefined.
90-
* }
91-
*
92-
* MyController.prototype.$onInit = function() {
93-
* // Bindings are now available in the $onInit lifecycle hook.
94-
* }
95-
* </hljs>
96-
*
97-
*/
9811
MdCompilerProvider.$inject = ['$compileProvider'];
99-
function MdCompilerProvider($compileProvider) {
100-
101-
var provider = this;
102-
103-
/**
104-
* @ngdoc method
105-
* @name $mdCompilerProvider#respectPreAssignBindingsEnabled
106-
*
107-
* @param {boolean=} respected update the `respectPreAssignBindingsEnabled` state if provided,
108-
* otherwise just return the current Material `respectPreAssignBindingsEnabled` state.
109-
* @returns {boolean|MdCompilerProvider} current value, if used as a getter, or itself (chaining)
110-
* if used as a setter.
111-
*
112-
* @description
113-
* Call this method to enable/disable whether Material-specific (dialog/panel/toast/bottomsheet)
114-
* controllers respect the AngularJS `$compileProvider.preAssignBindingsEnabled` flag. Note that
115-
* this doesn't affect directives/components created via regular AngularJS methods which
116-
* constitute most Material and user-created components.
117-
*
118-
* If disabled (`false`), the compiler assigns the value of each of the bindings to the
119-
* properties of the controller object before the constructor of this object is called.
120-
* The ability to disable this settings is **deprecated** and will be removed in
121-
* AngularJS Material 1.2.0.
122-
*
123-
* If enabled (`true`) the behavior depends on the AngularJS version used:
124-
*
125-
* - `<1.5.10`
126-
* - Bindings are pre-assigned.
127-
* - `>=1.5.10 <1.7`
128-
* - Respects whatever `$compileProvider.preAssignBindingsEnabled()` reports. If the
129-
* `preAssignBindingsEnabled` flag wasn't set manually, it defaults to pre-assigning bindings
130-
* with AngularJS `1.5` and to calling the constructor first with AngularJS `1.6`.
131-
* - `>=1.7`
132-
* - The compiler calls the constructor first before assigning bindings and
133-
* `$compileProvider.preAssignBindingsEnabled()` no longer exists.
134-
*
135-
* Defaults
136-
* - The default value is `false` in AngularJS 1.6 and earlier.
137-
* - It is planned to fix this value to `true` and not allow the `false` value in
138-
* AngularJS Material 1.2.0.
139-
*
140-
* It is recommended to set this flag to `true` when using AngularJS Material 1.1.x with
141-
* AngularJS versions >= 1.5.10. The only reason it's not set that way by default is backwards
142-
* compatibility.
143-
*
144-
* By not setting the flag to `true` when AngularJS' `$compileProvider.preAssignBindingsEnabled()`
145-
* is set to `false` (i.e. default behavior in AngularJS 1.6 or newer), unit testing of
146-
* Material Dialog/Panel/Toast/BottomSheet controllers using the `$controller` helper
147-
* is problematic as it always follows AngularJS' `$compileProvider.preAssignBindingsEnabled()`
148-
* value.
149-
*/
150-
var respectPreAssignBindingsEnabled = false;
151-
this.respectPreAssignBindingsEnabled = function(respected) {
152-
if (angular.isDefined(respected)) {
153-
respectPreAssignBindingsEnabled = respected;
154-
return this;
155-
}
156-
157-
return respectPreAssignBindingsEnabled;
158-
};
159-
160-
/**
161-
* @private
162-
* @description
163-
* This function returns `true` if AngularJS Material-specific (dialog/panel/toast/bottomsheet)
164-
* controllers have bindings pre-assigned in controller constructors and `false` otherwise.
165-
*
166-
* Note that this doesn't affect directives/components created via regular AngularJS methods
167-
* which constitute most Material and user-created components; their behavior can be checked via
168-
* `$compileProvider.preAssignBindingsEnabled()` in AngularJS `>=1.5.10 <1.7.0`.
169-
*
170-
* @returns {*} current preAssignBindingsEnabled state
171-
*/
172-
function getPreAssignBindingsEnabled() {
173-
if (!respectPreAssignBindingsEnabled) {
174-
// respectPreAssignBindingsEnabled === false
175-
// We're ignoring the AngularJS `$compileProvider.preAssignBindingsEnabled()` value in this case.
176-
return true;
177-
}
178-
179-
// respectPreAssignBindingsEnabled === true
180-
181-
// This check is needed because $compileProvider.preAssignBindingsEnabled does not exist prior
182-
// to AngularJS 1.5.10, is deprecated in AngularJS 1.6.x, and removed in AngularJS 1.7.x.
183-
if (typeof $compileProvider.preAssignBindingsEnabled === 'function') {
184-
return $compileProvider.preAssignBindingsEnabled();
185-
}
186-
187-
// Flag respected but not present => apply logic based on AngularJS version used.
188-
if (angular.version.major === 1 && angular.version.minor < 6) {
189-
// AngularJS <1.5.10
190-
return true;
191-
}
192-
193-
// AngularJS >=1.7.0
194-
return false;
195-
}
12+
function MdCompilerProvider() {
19613

19714
this.$get = ["$q", "$templateRequest", "$injector", "$compile", "$controller",
19815
function($q, $templateRequest, $injector, $compile, $controller) {
@@ -205,10 +22,10 @@ function MdCompilerProvider($compileProvider) {
20522
* @module material.core.compiler
20623
* @description
20724
* The $mdCompiler service is an abstraction of AngularJS's compiler, that allows developers
208-
* to easily compile an element with options like in a Directive Definition Object.
25+
* to compile an element with options like in a Directive Definition Object.
20926
*
21027
* > The compiler powers a lot of components inside of AngularJS Material.
211-
* > Like the `$mdPanel` or `$mdDialog`.
28+
* > Like the `$mdPanel` or `$mdDialog` services.
21229
*
21330
* @usage
21431
*
@@ -243,11 +60,11 @@ function MdCompilerProvider($compileProvider) {
24360
* });
24461
* </hljs>
24562
*
246-
* > Content Element is a significant performance improvement when the developer already knows that the
247-
* > compiled element will be always the same and the scope will not change either.
63+
* > Content Element is a significant performance improvement when the developer already knows
64+
* > that the compiled element will be always the same and the scope will not change either.
24865
*
249-
* The `contentElement` option also supports DOM elements which will be temporary removed and restored
250-
* at its old position.
66+
* The `contentElement` option also supports DOM elements which will be temporary removed and
67+
* restored at its old position.
25168
*
25269
* <hljs lang="js">
25370
* var domElement = document.querySelector('#myElement');
@@ -357,8 +174,8 @@ function MdCompilerProvider($compileProvider) {
357174
};
358175

359176
/**
360-
* Instead of compiling any template, the compiler just fetches an existing HTML element from the DOM and
361-
* provides a restore function to put the element back it old DOM position.
177+
* Instead of compiling any template, the compiler just fetches an existing HTML element from the
178+
* DOM and provides a restore function to put the element back it old DOM position.
362179
* @param {!Object} options Options to be used for the compiler.
363180
*/
364181
MdCompilerService.prototype._prepareContentElement = function(options) {
@@ -487,33 +304,10 @@ function MdCompilerProvider($compileProvider) {
487304
* @returns {!Object} Created controller instance.
488305
*/
489306
MdCompilerService.prototype._createController = function(options, injectLocals, locals) {
490-
var ctrl;
491-
var preAssignBindingsEnabled = getPreAssignBindingsEnabled();
492-
// The third argument to $controller is considered private and undocumented:
493-
// https://github.com/angular/angular.js/blob/v1.6.10/src/ng/controller.js#L102-L109.
494-
// TODO remove the use of this third argument in AngularJS Material 1.2.0.
495-
// Passing `true` as the third argument causes `$controller` to return a function that
496-
// gets the controller instance instead of returning the instance directly. When the
497-
// controller is defined as a function, `invokeCtrl.instance` is the *same instance* as
498-
// `invokeCtrl()`. However, when the controller is an ES6 class, `invokeCtrl.instance` is a
499-
// *different instance* from `invokeCtrl()`.
500-
if (preAssignBindingsEnabled) {
501-
var invokeCtrl = this.$controller(options.controller, injectLocals, true);
502-
503-
if (options.bindToController) {
504-
angular.extend(invokeCtrl.instance, locals);
505-
}
506-
507-
// Use the private API callback to instantiate and initialize the specified controller.
508-
ctrl = invokeCtrl();
509-
} else {
510-
// If we don't need to pre-assign bindings, avoid using the private API third argument and
511-
// related callback.
512-
ctrl = this.$controller(options.controller, injectLocals);
307+
var ctrl = this.$controller(options.controller, injectLocals);
513308

514-
if (options.bindToController) {
515-
angular.extend(ctrl, locals);
516-
}
309+
if (options.bindToController) {
310+
angular.extend(ctrl, locals);
517311
}
518312

519313
if (options.controllerAs) {
@@ -534,7 +328,7 @@ function MdCompilerProvider($compileProvider) {
534328
*/
535329
MdCompilerService.prototype._fetchContentElement = function(options) {
536330
var contentEl = options.contentElement;
537-
var restoreFn = null;
331+
var restoreFn;
538332

539333
if (angular.isString(contentEl)) {
540334
contentEl = document.querySelector(contentEl);

0 commit comments

Comments
 (0)