How do I allow for clicking on each item/post, then viewing it in a new screen?

Im trying to build a simple tutorial app list of grocery items, and then clicking on it will lead to a new page showing the grocery goods in details, such as price, quantity left etc.

Currently, clicking on the comments button does nothing. I see a twitch in the URL but it reverts back to its original posts url. No syntax issues so far.

I suspect it might by either naming convention of the states or the angular.module definitions gone wrong. Can someone enlighten me please? Thanks!


This is the stateProvider codes

app.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider

.state('tab', {
  url: '/tab',
  abstract: true,
  templateUrl: 'templates/tabs.html'})

.state('tab.posts', {
  url: '/posts',
  views: {
    'tab-posts': {
      templateUrl: 'templates/tab-posts.html',
      controller: 'PostsCtrl'}}})

.state('tab.view', {       //suspect error is here but various combos didnt work
  url: '/posts/:postId', 
  views: {
    'tab-view':{
      templateUrl: 'templates/tab-showpost.html',
      controller: 'PostViewCtrl'}}})


This is the postview.js file

var app = angular.module('app.controllers.view', []) //error even if remove this line 
app.controller('PostViewCtrl', function ($scope, $stateParams, Post) {
    $scope.post = Post.find($stateParams.postId);
});


This is the tab-showpost.html

<a href="{{ post.url }}">{{ post.title }}</a>
<a href="#/posts">Back to Posts</a>


This is the tab-posts.html

   <form ng-submit="submitPost()">
        <input type = "text" ng-model="post.title"/>
        <input type = "text" ng-model="post.url"/>      
        <input type = "submit" value="Add Post"/>
    </form>     
    <div ng-repeat="(postId, post) in posts">             
      <a href="{{ post.url }}">{{ post.title }}</a>
      <a href="#/posts/{{ postId }}">comments</a>  
    </div>

I think it cannot resolve your url, maybe this has to do with the way you named your routes and how they inherit eachother. Shouldnt they url be #/tab/posts/{{ postId }} ?

Else you could try and see if it works with a ^ to make the route absolute and not relative to the parent.

So to make the url work, try

.state('tab.view', {       //suspect error is here but various combos didnt work
  url: '^/posts/:postId', 
  views: {
    'tab-view':{
      templateUrl: 'templates/tab-showpost.html',
      controller: 'PostViewCtrl'}}})

Else it will take on the path relative to its parent, tab in this case if i am correct and thus have the url #/tab/posts/{{ postId }}.

Not completely sure that I understand your app structure, but here is a working example, which should follow your design

Firstly, because the 'tab' state is parent for both children tab.posts and tab.view, I placed both targets inside of the tabs.html:

<div>
  <h3>Tabs</h3>
  <hr />
  <div ui-view="tab-posts"></div>
  <div ui-view="tab-view"></div>
</div>

NOTE: in fact, there could be just one even unnamed template <div ui-view=""></div> and both states can target that like this views : { '' : {...

The way, how we can go to comments from a list view is expressed this way:

  <a href="#/tab/{{ postId }}">comments</a>  
  <a ui-sref="tab.view({postId: postId})">comments</a>

The rest of your draft is mostly unchanged, just do not forget to reference all modules in the root one:

var app = angular.module('myApp', [
  'app.controllers.view',
  'ui.router'
]);

The working plunker is here

Instead of:

<a href="#/posts/{{ postId }}">comments</a> 

I prefer using state names in refs so that the angular will resolve the url for you. It's simpler if you do:

<a ui-sref="tab.view({postId:postId})">comments</a>