The angular ui-router allows multiple nested views. The role of these interchangeable views seems to overlap the role of directives.
What are the pros/cons to using (multiple, nested) ui-view
s vs angular's directives?
UPDATE
States and routing are 2 different functions. States allow you to swap out partial.html templates and their controllers, and you can (optionally?) specify a corresponding URL/route.
In an email response from Tim Kindberg (a ui-router
dev):
ui-view is a directive, so if you use it you are using a directive
that has been worked on particular to work well with the rest of the
ui-router module. I can't imagine it being easy to roll your own
directive to replace this functionality.
And to this, it seems you could have 2 options:
Normal Directives:
app.directive('myDir1', {/* controller: ... */})
.directive('myDir2', {/* controller: ... */})
vs ui-view "Directives"
$stateProvider.state('route1', {
/* url: "/route1", // optional?? */
views: {
"myDir1": { templateUrl: "myDir1.html" /* , controller: ... */ },
"myDir2": { templateUrl: "myDir2.html" /* , controller: ... */ }
}
})
Bonus question:
Are normal angular directive features available to views? Such as:
- Transclude
- Replace
- Isolate scoping
- Compile / linking functions
If ui-views ARE directives, it seems clear their usage is different. Wouldn't it make sense to harmonize these models?
How about if you used Angular UI router's inline views to point to directives?
Let's say you have a directive for a table that handles CRUD operations on user accounts. We'll say the directive is named user-admin
. Our routes file would look like:
.state('users', {
url: '/users',
template: "<user-admin>"
});
This would give you many nice things:
- Allow you to have a url that points straight to a directive
- Removes the duplication of needing two templates (view template and directive template) when a state is just a directive
- Allow you to start moving more controller logic into directives in prep for Angular 2.0. See here and here.
After some thinking/ correspondence, here's my conclusion:
ui-views define containers, and states define what goes in those containers
When you put a ui-view='containerName'
directive on an element, you're setting up a container that holds something. You haven't yet said anything about what goes in there.
When you create your $stateProvider.state(...)
definitions, you're specifying what goes in these containers:
$stateProvider.state('someState', {
views: {
"containerName": { templateUrl: "someContents.html" /* , controller: ... */ },
"container2": { templateUrl: "otherContents.html" /* , controller: ... */ }
}
})
Can you use all the traditional directive functionality (transclude, replace, isolate scoping, compile/linking functions) with your ui-views? I'm not sure. For example:
$stateProvider.state('someState', {
views: {
"containerName": {
templateUrl: "someContents.html",
scope: { localVar: "@" }, // can you
transclude: true, // do this?
controller: function(){}
},
"container2": { templateUrl: "otherContents.html" /* , controller: ... */ }
}
})
In conclusion, it seems like each option has its tradeoffs. Directives have some additional features, yet ui-views are interchangeable and can have routes associated.
It seems you can do something like this with relative impunity:
$stateProvider.state('general', {
url: '/general',
views: {
main: {
template: '<general-directive></general-directive>'
}
}
});
**In Config function:**
.state('list', {
url:'/list',
template:'<user-info-table></user-info-table>',
controller:'UserInfoTableController',
});
**In Directive:**
angular.module('UserInfo').directive("userInfoTable", function() {
return {
templateUrl:'templates/UserInfoTable.html',
restrict:'EA',
};
});