С компонентом angular и ui-router может ли один контроллер иметь несколько шаблонов?

В компоненте я хотел бы связать шаблоны с действиями CRUD, но использовать один контроллер, который обрабатывает данные для всех из них. Имеет ли это смысл с компонентами angular или мне следует использовать несколько компонентов? Как будет выглядеть конфигурация состояния ui-router?

EDIT: компоненты имеют шаблоны, а также состояния пользовательского интерфейса. Меня смущает артикуляция этих двух понятий.

EDIT 2: пытаюсь прояснить мое понимание:

  • компонент - это контроллер + шаблон + привязки. Контроллер можно не указывать.
  • состояния: URL + шаблон + контроллер или URL + компонент. Контроллер можно не указывать.

Таким образом, кажется, что компоненты берут на себя некоторые обязанности, которые раньше принадлежали ui-router.

Моя цель здесь:

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

я должен делать :

составные части:

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

а затем маршрутизация:

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

?

EDIT 3: цитата из https://docs.angularjs.org/guide/component :

«В компонентном приложении каждое представление является компонентом»

цитата из https://ui-router.github.io/guide/ng1/route-to-component :

«Компонентная модель обеспечивает разделение проблем и инкапсуляцию с помощью изолированной области. К данным из родительских областей больше нельзя получить прямой доступ. Вместо этого они должны быть явно подключены».


person Olivvv    schedule 29.03.2017    source источник


Ответы (3)


Да, это возможно. Ваша конфигурация ui-router будет выглядеть примерно так: (Несколько state с одинаковыми контроллерами.)

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

Вот рабочий пример использования нескольких состояний и шаблонов с использованием одного и того же контроллера.


Изменить: вам не обязательно использовать components. Зачем создавать три разных дополнительных компонента, если можно добиться того же и без них? Я бы по-прежнему рекомендовал подход, о котором я упоминал выше. Всегда следует выбирать получение того же результата с меньшим объемом кода. :)

Цитируя Эрика Эллиота в Твиттере,

Код временный. Он существует, пока полезен. Если код заменяется лучшим кодом, хорошо! Если код можно удалить, празднуйте!

person tanmay    schedule 29.03.2017
comment
спасибо, но я спросил это конкретно об угловых компонентах. Компоненты также определяют шаблон, поэтому я запутался между шаблоном ui-router и шаблоном компонента. - person Olivvv; 29.03.2017
comment
mmmh Я полагаю, что это очень актуальный вопрос, по-видимому, у меня есть angular: ^ 1.5.2, angular-ui-router: ^ 0.3.1, который трансформируется в 0.3.2. Попробую ui-router версии 1.0 alpha. в настоящее время. - person Olivvv; 29.03.2017
comment
на самом деле я сейчас в замешательстве. Есть angular-ui-router && ui-router. Я предполагаю, что один является разветвлением другого на угловой. если у вас есть какие-либо рекомендации, я возьму это. Все, что лучше всего подходит для использования с угловыми компонентами. - person Olivvv; 29.03.2017
comment
@Olivvv angular-ui-router - person tanmay; 29.03.2017
comment
Я бы рекомендовал использовать компоненты вместо контроллеров, и я не согласен с вашей цитатой Эрика Эллиота в этом случае. Намеренное использование устаревших концепций, потому что «так проще и меньше работы», также известно как лень. - person Dan; 29.03.2017
comment
@DanPantry Я согласен с вами, но поскольку все компоненты используют один и тот же контроллер, но разные шаблоны, я склонялся к этому подходу - person tanmay; 29.03.2017
comment
@DanPantry, не могли бы вы тогда поделиться предложенным кодом / архитектурой? - person Olivvv; 29.03.2017
comment
@tanmay В настоящее время я обновляю свои знания до es6 / ng1.5, поэтому каждый шаг более болезненный, чем с хорошо известным старым стеком. Но здесь я уверен, что компоненты были продуманы с учетом грубости. Должен быть правильный путь, я просто пока не вижу его ясно, но хочу узнать. Кроме того, у меня действительно нет выбора, чтобы не использовать компоненты, это руководство компании. У них есть видение, я реализую... - person Olivvv; 29.03.2017

Ваш провайдер состояния будет выглядеть так

JS-код

        $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'
          }
        }
      })

в одном состоянии вы можете загрузить несколько представлений

HTML

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

см. несколько представлений

person Jayant Patil    schedule 29.03.2017
comment
Как уже было сказано, я прошу именно архитектуру компонентов. Компоненты также имеют шаблоны. - person Olivvv; 29.03.2017
comment
так что вы можете добавить туда также - person Jayant Patil; 29.03.2017

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'
  })

В дополнение к нашим комментариям вы можете использовать что-то вроде приведенного выше. Это довольно многословно, но это Angular 1.5 для вас. Не проверял, работает ли это, но это основное представление о том, как это могло бы работать.

Главный вывод заключается в том, что у вас есть компонент route1, который обрабатывает только элементы связывания маршрута (например, URL-адрес, разрешения и т. д.) и передает эту информацию своим дочерним элементам (которых нет).

routeView1 просто отображает, как будет работать маршрут, и использует require для связи с некоторым родительским API, который является общим (вы также можете использовать односторонние привязки для этого, если хотите, но с большим количеством методов это приводит к грязному шаблону).

sharedBehaviour содержит только то общее поведение, которое вы хотите отобразить для любого переданного ему дочернего элемента.


По общему признанию, это это довольно беспорядочно, и я бы предпочел, чтобы вместо этого вы использовали односторонние привязки для route-view-1 и обрабатывали связывание в shared-behaviour, но это может быть довольно много повторений. Вы могли бы использовать магию трансклюзии, чтобы решить эту проблему, но это... не стоит того.

Я бы настоятельно не рекомендовал бы совместно использовать контроллеры, как предлагали другие ответчики. В Angular 2 и выше контроллер является компонентом. Вы разделяете поведение там, делая что-то похожее на то, что сделал я (или используя односторонние привязки с обратными вызовами) и используя композицию.


Кстати, как упоминалось в моем ответе, более новые версии UI-Router для Angular 1.5 позволяют вам указать компонент для рендеринга, а не шаблон. См. здесь для получения дополнительной информации.

person Dan    schedule 29.03.2017
comment
Я изучаю ваш ответ. Под более новыми версиями вы подразумеваете 1.0.0-rc.1, верно? github.com/angular-ui/ui-router/releases - person Olivvv; 29.03.2017
comment
Я правильно понимаю, что вы рекомендуете отдельные компоненты для чтения, создания и обновления? - person Olivvv; 29.03.2017
comment
Я бы рекомендовал вам иметь компонент для отображения каждого маршрута. У вас может быть один компонент со всем общим поведением, если вы хотите, хотя чем больше вы это описываете, тем больше кажется, что вам нужен сервис, который обрабатывает операции CRUD. - person Dan; 29.03.2017