Last hours I have been reading through docs of UI-Router. But I can't find a solution for my problem.
My webapp has two different columns, a list on the left and a detail view on the right. Selecting a element of the list should show detail information on the right.
Which of this two approaches described in the title would you prefer? When to use what?
As with ng-Route, with this approach views and routes have not tied to the browser URL. You can change the view even if the browser URL does not change. Suggested read:
Notice, in the app.js file how each state contains one or more named views and how each named view is injected in the ui-view declared in its name. Please consider the code in the Plunker, if you navigate to the “Example Tabs” and then click on the “Content tab” you will see a “Replace Content” button.
This sample is heavily borrowed from AngularJS Routing Using UI-Router. So, here is our default file: index.html: This is the result of the codes in this tutorial.
The solution comes with ui-router itself, under the name of ( multiple ) named views. In practice, instead of just decorating a state with a single view (and a controller) we consider a state as, potentially, made of many views. Each view will be identified via its own name and will have its own controller (and data).
In fact, the List x Detail scenario is the most suitable for ui-router. These are in fact two states, the parent/child (i.e. child states to answer the question):
List view (e.g. the left column). This could be a dynamic view, with paging, sorting and filtering, but still - this will always be a gateway, a parent to:Detail view (e.g. the right column). To select a detail (unless navigating via url directly) we simply need a List view. To select different detail, we can profit from a fact, that the parent/List view state is not reloading, while iterating among many details...The best we can do is to observe the example, provided by ui-router team:
And we can also see its definition, which is part of this states definition:
this link, belongs to the best documented pieces of code I do remember... It explains everything and also helps to learn how the ui-router state definition is working. 
Below I tried to show that power by citing the definition of the List and Detail states.
The List state:
/////////////////////
// Contacts > List //
/////////////////////
// Using a '.' within a state name declares a child within a parent.
// So you have a new state 'list' within the parent 'contacts' state.
.state('contacts.list', {
    // Using an empty url means that this child state will become active
    // when its parent's url is navigated to. Urls of child states are
    // automatically appended to the urls of their parent. So this state's
    // url is '/contacts' (because '/contacts' + '').
    url: '',
    // IMPORTANT: Now we have a state that is not a top level state. Its
    // template will be inserted into the ui-view within this state's
    // parent's template; so the ui-view within contacts.html. This is the
    // most important thing to remember about templates.
    templateUrl: 'app/contacts/contacts.list.html'
})
the Detail state:
///////////////////////
// Contacts > Detail //
///////////////////////
// You can have unlimited children within a state. Here is a second child
// state within the 'contacts' parent state.
.state('contacts.detail', {
    // Urls can have parameters. They can be specified like :param or {param}.
    // If {} is used, then you can also specify a regex pattern that the param
    // must match. The regex is written after a colon (:). Note: Don't use capture
    // groups in your regex patterns, because the whole regex is wrapped again
    // behind the scenes. Our pattern below will only match numbers with a length
    // between 1 and 4.
    // Since this state is also a child of 'contacts' its url is appended as well.
    // So its url will end up being '/contacts/{contactId:[0-9]{1,8}}'. When the
    // url becomes something like '/contacts/42' then this state becomes active
    // and the $stateParams object becomes { contactId: 42 }.
    url: '/{contactId:[0-9]{1,4}}',
    // If there is more than a single ui-view in the parent template, or you would
    // like to target a ui-view from even higher up the state tree, you can use the
    // views object to configure multiple views. Each view can get its own template,
    // controller, and resolve data.
    // View names can be relative or absolute. Relative view names do not use an '@'
    // symbol. They always refer to views within this state's parent template.
    // Absolute view names use a '@' symbol to distinguish the view and the state.
    // So 'foo@bar' means the ui-view named 'foo' within the 'bar' state's template.
    views: {
        // So this one is targeting the unnamed view within the parent state's template.
        '': {
            templateUrl: 'app/contacts/contacts.detail.html',
            controller: ['$scope', '$stateParams', 'utils',
            function ( $scope, $stateParams, utils) {
                $scope.contact = utils.findById($scope.contacts, $stateParams.contactId);
            }]
        },
        // This one is targeting the ui-view="hint" within the unnamed root, aka index.html.
        // This shows off how you could populate *any* view within *any* ancestor state.
        'hint@': {
            template: 'This is contacts.detail populating the "hint" ui-view'
        },
        // This one is targeting the ui-view="menu" within the parent state's template.
        'menuTip': {
            // templateProvider is the final method for supplying a template.
            // There is: template, templateUrl, and templateProvider.
            templateProvider: ['$stateParams',
            function ( $stateParams) {
                // This is just to demonstrate that $stateParams injection works for templateProvider.
                // $stateParams are the parameters for the new state we're transitioning to, even
                // though the global '$stateParams' has not been updated yet.
                return '<hr><small class="muted">Contact ID: ' + $stateParams.contactId + '</small>';
            }]
        }
    }
})
Summary: In these scenarios, do use the parent/child state definition, because the parent will be loaded only once, and keep its data, while we are iterating among its children
Check these links for some more details:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With