0

In a component I would like to associate templates to CRUD actions, but use a single controller that handles data for all all of them. Does this make sense with angular components, or should I use several components ? How would the ui-router state configuration look like ?

EDIT: Components have templates, and ui-router states too. I am confused about the articulation of those 2 concepts.

EDIT 2: trying to clarify my understanding so far :

  • component are controller + template + bindings. Controller can be omitted.
  • states are url + template + controller or url + component. Controller can be omitted.

So it seems that components are taking away some of the responsabilities that use to belong to ui-router.

My goal here:

 - url1 --> controller foo + template x;
 - url2 --> controller foo + template y;
 - url3 --> controller foo + template z;

should I do :

components:

component x --> controller foo + template x;
component y --> controller foo + template y;
component z --> controller foo + template z;

and then routing:

url 1 --> component x
url 2 --> component y
url 3 --> component z

?

EDIT 3: quote from https://docs.angularjs.org/guide/component :

"In a component-based application, every view is a component"

quote from https://ui-router.github.io/guide/ng1/route-to-component :

"The component model enforces separation of concerns and encapsulation by using an isolate scope. Data from parent scopes can no longer be directly accessed. Instead, it needs to be explicitly wired in"

3 Answers 3

2

Yes, it is possible. Your ui-router config would look something like this: (Multiple states having same controllers.)

.state('add', {
    url: '/add',
    templateUrl: 'templates/add.html',
    controller: 'contactCtrl'
})
.state('edit', {
    url: '/edit',
    templateUrl: 'templates/edit.html',
    controller: 'contactCtrl'
})

Here's a working example of having multiple states and templates using same controller.


Edit: You don't have to use components. Why create three different extra components while you can achieve the same thing without them? I would still recommend the approach I mentioned above. Getting the same outcome with lesser code should always be chosen. :)

Quoting Eric Elliot on twitter,

Code is temporary. It exists while it is useful. If code is replaced by better code, good! If code can be deleted, celebrate!

Sign up to request clarification or add additional context in comments.

8 Comments

thanks but I asked this specifically about angular components. Components define a template too, so I am confused between ui-router template a component template.
mmmh I suppose this is a very relevant question apparently I have "angular": "^1.5.2", "angular-ui-router": "^0.3.1" which trnalsates into 0.3.2 installed. I'll try ui-router version 1.0 alpha. now.
actually I am confused now. There is angular-ui-router && ui-router. I guess one is a fork of the other into angular. if you have any recommendation I'll take it. Whatever is best for use with angular components.
@Olivvv angular-ui-router
I'd recommend using components instead of using controllers and I disagree with your quote by Eric Elliot in this instance. Purposefully using deprecated concepts because 'It's easier this way and it's less work' is also known as laziness.
|
0

Your state provider will look like this

JS code

        $stateProvider
      .state('report', {
        views: {
          'filters': {
            templateUrl: 'report-filters.html',
            controller: 'ctrl'
          },
          'tabledata': {
            templateUrl: 'report-table.html',
            controller: 'ctrl'
          },
          'graph': {
            templateUrl: 'report-graph.html',
            controller: 'ctrl'
          }
        }
      })

in single state you can load multiple views

HTML

  <body>
    <div ui-view="filters"></div>
    <div ui-view="tabledata"></div>
    <div ui-view="graph"></div>
  </body>  

refer multiple views

2 Comments

As said, I ask specifically for a components architecture. Components have templates as well.
so you can add there also
0
angular.module('', [])
  // Route handler touches this
  .component('route1', {
    template: `<shared-behaviour>
      <route-view-1></route-view-1>
    </shared-behaviour>`
  })
  // This is a purely visual component that links actions with the shared behaviour component
  .component('routeView1', {
    require: {
      shared: '^sharedBehaviour'
    },
    template: '<button ng-click="$ctrl.onClick()></button>',
    controller: class RouteView2Ctrl {
      onClick() {
        this.shared.onSharedClick()
      }
    }
  })
  // Contains the shared behaviour that is shared across the multiple routes
  .component('sharedBehaviour', {
    // Tell Angular to render children passed to this component
    transclude: true,
    template: '<div ng-transclude></div>',
    controller: class SharedBehaviourCtrl {
      onSharedClick() {
        /// do something
      }
    }
  })
  // Newest version of UI-Router
  .state('route1', {
    component: 'route1'
  })

Further to our comments, you could use something like the above. It's pretty verbose, but that's Angular 1.5 for you. Haven't tested that it works, but it's a basic idea of how it might work.

The main take away being that you have the route1 component which only handles linking route stuff (like the url, resolves, etc) and passes that information to its children (of which there aren't any).

routeView1 just renders how the route would work, and uses require to talk to some parent API that is shared (you could also use one-way bindings for this if you wanted, but with lots of methods this leads to a messy template).

sharedBehaviour only contains the shared behaviour you want renders any child passed to it.


This is admittedly pretty messy and I would prefer that you instead used one-way bindings for route-view-1 and handled the linking in shared-behaviour, but this might be quite a bit of repetition. You could use some transclusion magic to solve that, but it's.. not really worth it.

I would really recommend against sharing controllers like other answerers have suggested. In Angular 2 and above, a controller is the component. You share behaviour there by doing something similar to what I have done (or by using one-way bindings with callbacks) and using composition.


BTW as mentioned in my answer, newer versions of UI-Router for Angular 1.5 allow you to specify a component to be rendered rather than a template. See here for more info.

3 Comments

I am studying your answer. By "newer versions" you mean "1.0.0-rc.1", right ? github.com/angular-ui/ui-router/releases
Do I understand right that you recommend to have seperate "read", "create", "update" components ?
I'd recommend you have a component for the display of each route. You could have a single component with all of the shared behaviour if you wanted, although the more you describe this, the more it sounds like you want a service that handles the CRUD operations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.