-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat($compile/ngBind): don't add binding info if not enabled #8430
feat($compile/ngBind): don't add binding info if not enabled #8430
Conversation
Closes #8423 |
Note that previous commits moved the adding of the CSS class into the compile function from the post-link function to aid performance. But since we are now removing these calls altogether during production there is little benefit in this performance fix. |
LGTM |
.config(['$compileProvider', function($compileProvider) { | ||
$compileProvider.enableBindingInfo(); | ||
}]); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be moved into Protractor (and Batarang) itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, definitely. We'll just check if the function (enableBindingInfo
) exists for backward compatibility.
@@ -118,11 +119,11 @@ var ngBindDirective = ngDirective({ | |||
</file> | |||
</example> | |||
*/ | |||
var ngBindTemplateDirective = ['$interpolate', function($interpolate) { | |||
var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) { | |||
return function(scope, element, attr) { | |||
// TODO: move this to scenario runner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly unrelated: do we know what this todo was for? Can we remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know. +1 for removing.
how about removing all the this change would make debugging much harder though and in that case we might want to turn on the debugging mode by default in non-minified version. I was also thinking about how could we easily tell if we are in minified or non-minified mode, and one solution that came to my mind was to check too crazy? thoughts? |
@IgorMinar - regarding turning this on for non-minified builds: @tbosch made a good point that we should be running E2E tests against minified code, so we would still need to have a switch to turn it on for most Protractor scenarios. Given that, I don't think there is much point in spending a long time working out how to tell if we are minified or not. More simply we could have a module (or just a config block), which turns on the bindingInfo. This would live in a separate source file and include it only in the non-minified build. |
@petebacondarwin if we don't publish |
We could to the following:
Regarding removing all the $scope info from data as well in debug mode:
|
My 2c - |
So, say we have a module called Turning on the debug stuff would then be simply a case of loading this and adding a dependency on it to the app module. There are two approaches we could consider:
|
+1 for not forcing devs to reload the page with some injected module in order to access jqLite angular helpers. |
@@ -859,6 +886,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { | |||
} | |||
}; | |||
|
|||
|
|||
function safeAddClass($element, className) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we just get rid of this fn and use jqLiteAddClass instead? that should work for all elements regardless of whether they are svg or not
In the current state I don't see how this will be off by default in production but on in development. That bit is missing. I left a few other comments on the individual commits. nothing major. |
Will the jQuery/jqLite |
@IgorMinar I thought we agreed not to change it based on the minification? I think it would actually lead to more confusion because people might use They should proactively turn it on using |
@jbedard what is your production use case for I would think that a noop would be more confusing since the app semantic would quietly change. |
I have a few cases such as...
Most of those I can easily change to fetch the scope differently because the directive controls the child elements (and I can manage the DOM<=>scope myself). What about cases such as ngRepeat though? Does ngRepeat provide a way to get the scope based on the repeated DOM element? I know this pattern isn't really encouraged and using a local ngEvent per repeated element would be preferred but that is often too expensive (at link time due to more linking + jQuery.on and at event firing time due to the unnecessary digests when It would be very nice to have no jQuery data by default during compile/link though. The scope (and controllers?) could be put directly on the DOM instead of in jQuery data... |
@jbedard in this case you should just use $rootScope as it has the same effect unless you are hoping to make use of localApply in which case you really should be in a closure containing the appropriate scope anyway |
@petebacondarwin my point was that within the |
@jbedard - Oh I didn't notice the content of that comment. |
I rebased this PR on the latest master and addressed all the comments. |
@petebacondarwin but how would that directive fetch the scope of the delegated event target without |
Talked with @IgorMinar and we decided to enable the debugging by default. That means this is not a breaking change. We also talked about the possibility to make the debug info enabled in non-minified build and disabled in the minified build. That could however lead to apps working in development and crashing in production. |
Thus I'm also renaming the config method to |
One more change, in order to follow convention of other APIs (eg. chaining), I'm gonna call this method |
But we also agreed to print into console what mode we are in when we
|
Also I think @jbedard's comment about access to scope in delegated events should be addressed. Not sure how to provide this if we turn off scopes. Any ideas? |
I'm not sure how to address that one without attaching the scope or its id
|
At least with the decision to make this optimization (removing scope info from DOM) opt-in it is less likely to break applications but we should ensure that this use case is highlighted in the docs. |
So to summarize. The config API is As long as Travis is happy, I'm gonna merge this in. If anybody wants to do a review, it's here: |
Merged as c6bde52 |
Yay!
|
Thanks @vojtajina !! |
This will be necessary after Angular commit angular/angular.js#8430 It should be a noop (which adds one webdriver command) for versions of Angular before that one.
The compiler and ngBind directives add binding information (
ng-binding
CSS class and
$binding
data object) to elements when they are bound tothe scope. This is only to aid testing and debugging for tools such as
Protractor and Batarang. In production this is unneccesary and add a
performance penalty.
This change disables adding this binding information by default. You can
enable it by calling
$compilerProvider.enableBindingInfo()
in a moduleconfig()
block.BREAKING CHANGE:
The
ng-binding
CSS class and the$binding
data object are no longerattached to DOM elements that have a binding to the scope, by default.
If you relied on this feature then you can re-enable it in one of your
application modules: