When I realized that ng-hide just applies CSS classes I did a huge facepalm. Consider the example of dynamically constructing a table. In Angular:
<tr ng-repeat="child in children">
<td ng-show="foo(child)">Foo</td>
<td ng-hide="foo(child)">Bar</td>
</tr>
This example runs the function foo four (!) times per digest cycle per item. Sure, you could convolute your code to make the Angular more performant, but at the cost of clear and maintainable markup. What's more, this produces rows with two cells, one of them hidden with CSS, which is ripe for creating hard-to-debug issues. The alternative in basically any other framework is written in a way and produces code execution and markup that you'd intuitively expect.Angular's directive system encourages developers to write illegal markup. Enough said.
Angular's DI system is needlessly complicated, and the basic usage breaks when minifying because it couples identifier names to string values.
That same issue is repeated in many different aspects of Angular: the basic, intuitive usage is (intentionally or not) broken in a production environment. The amount of deep knowledge of the Angular framework that's required to successfully develop apps is absurd.
[0]: https://www.airpair.com/angularjs/posts/angularjs-performanc...