You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Sep 8, 2020. It is now read-only.
Copy file name to clipboardExpand all lines: TIPS-AND-TRICKS.md
+45Lines changed: 45 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,3 +23,48 @@ Keep your `$scope.$apply()` [as close to the top of your stack trace as possible
23
23
The point of putting the logged in user in the top-level (`authentication state`) resolve is that all of your code can act on this data synchronously and leverage more `bind-once` in your views. If the user logs in or out, **you should reload the entire state tree with the re-resolved `authUser`.** This is because adding listeners for a user logging in and out in your entire codebase causes a massive amount of overhead, and you have to start coding listeners which deal with asynchronous lifecycles of users changing their state. Logging in and out happens at most once a week, so it's just better to not incur the performance and coding penalty just to allow simpler login.
24
24
25
25
Apps that don't let you access their content without being logged in don't have to deal with this use-case. Otherwise, `$state.reload()` or `$state.go('...', {}, { reload: true })` are your friends.
26
+
27
+
#### Don't use `controllerAs` in routes. Use it in directives only.
28
+
controller instances are not shareable. Meaning if you put logic into a controller (`this.doSomething()`) although you can reuse the logic elsewhere, you can’t reuse the instance
29
+
controllerAs syntax fixes a few issues, but I believe it will mislead people into thinking it’s okay to bloat controllers, which it isn’t (except for directives)
30
+
the reason is because your special logic that’s usually stateful shouldn’t be in the controller, it should be in something stateful that can be shared
31
+
so you should instead put most of your `this.doSomething()` into a factory, preferrably (if you follow my talks) a class or object instance
32
+
then you can share this factory/class/instance across multiple controllers, and not just the logic is shared, but also the highly stateful data
33
+
`resolve: { person: function(Person) { return new Person() } }`
34
+
you inject `person` into multiple controllers and they all share the same data, and they all update in sync
35
+
so instead of doing `this.doSomething()` in your controller, and keeping track of info about how a `Person` works inside a controller (which is reusable, but not shareable) you should keep it inside your factories, which are even FURTHER abstracted from the view/angular-centric mindset, but are also instantiatable and manageable
36
+
I can control more concretely when a person is created, destroyed, updated, who has access to it, how it gets reused, etc
37
+
angular no longer handles the lifecycle of the data, i do
38
+
my route-controllers are generally 2-10 lines of code
so my controller does nothing more than putting my business logic onto the view and occasionally wrapping business logic with view logic and / or route logic (edited)
42
+
now lets say you STILL wanted to use controllerAs yet still keep things organized the way i described
43
+
you CAN, except your bindings look like this: `<input ng-model=“personCtrl.person.name”>`
44
+
instead of just `<input ng-model=“person.name”>`
45
+
that is fairly trivial, mind you, but there is another big annoyance I have with it
46
+
your view is no longer reusable with different controllers
47
+
lets say i want to use the same view with a create vs edit controller
48
+
my view bindings have to be `<input ng-model=“createCtrl.person.name”>` or `<input ng-model=“updateCtrl.person.name”>`
49
+
or lets just say you call the controller `person` or `personCtrl`
50
+
then you could have a view person controller and inside of it a edit person controller
51
+
who gets which name?
52
+
no, when you start to build big apps and deal with these design questions, I find `controllerAs` is NOT the answer
53
+
I like having brittle scope bindings, for instance you may have cringed when i did `$scope.loading = true` because if you put a `ng-click=“loading = false”` inside of an `ng-if` it won’t work
54
+
except i want to keep my view-state flags shallow, simple, clean, and I don’t want the view to update them
55
+
I like having 2 controllers, both with their own `loading` flags
56
+
I prefer not having to namespace all my loading flags by my controller name or variable or state name, and yet my views simply don’t care
57
+
doing `ng-show=personLoading` is the same as doing `ng-show=personCtrl.loading`
58
+
my view becomes more brittle and heavily tied to controllers
59
+
it’s a weird like way of walking this fine line of things
60
+
but i’ve come to find i’m extremely happy with the architecture i’ve built and it scales ridiculously well
61
+
now in directives, it’s a completely different ballgame
62
+
that’s because *directives* are entirely about view logic, and should almost never do business logic. Period.
63
+
and anyone who things otherwise I humbly disagree with.
64
+
Now the thing is, the old way of doing directives you put all your shit into a linking function
65
+
a directive controller is essentially identical to a linking function except it is reusable by other directives
66
+
so it’s a visual-widgets externally visible api
67
+
so if you look at `ui-select` i love controllerAs because I can give it methods like `uiSelectCtrl.open()`
68
+
and that really is what it’s doing. It’s the controls for my ui-select widget
69
+
`personCtrl.person.open()` just doesn’t make sense if you read it. The ‘controller’ (guy doing shit to people) isn’t the one with the method, the object itself has methods that work upon itself
70
+
and doing `personCtrl.open()` is just a sign of bad design, because skinny controllers
0 commit comments