【问题标题】:With angular component and ui-router, can a single controller have multiple templates?使用角度组件和ui-router,单个控制器可以有多个模板吗?
【发布时间】:2017-08-22 15:27:21
【问题描述】:

组件中,我想将模板与 CRUD 操作相关联,但使用单个控制器来处理所有这些操作的数据。这对角度组件有意义吗,还是我应该使用多个组件? ui-router 状态配置如何?

编辑: 组件有模板,也有 ui-router 状态。我对这两个概念的表达感到困惑。

编辑 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

?

编辑 3: 引用https://docs.angularjs.org/guide/component

“在基于组件的应用程序中,每个视图都是一个组件”

来自https://ui-router.github.io/guide/ng1/route-to-component 的引用:

“组件模型通过使用隔离作用域来强制分离关注点和封装。不能再直接访问来自父作用域的数据。相反,它需要显式连接”

【问题讨论】:

    标签: angularjs angular-ui-router angular-components angular-component-router


    【解决方案1】:

    是的,这是可能的。您的 ui-router 配置看起来像这样:(多个 states 具有相同的控制器。)

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

    这是一个 working example 使用同一个控制器的多个状态和模板。


    编辑:您不必使用components。为什么要创建三个不同的额外组件,而无需它们也能实现相同的目标?我仍然会推荐我上面提到的方法。应始终选择使用更少的代码获得相同的结果。 :)

    在推特上引用Eric Elliot

    代码是临时的。它在有用的时候就存在。 如果代码被更好的代码代替,很好! 如果代码可以删除,庆祝!

    【讨论】:

    • 谢谢,但我专门询问了有关角度组件的问题。组件也定义了一个模板,所以我在 ui-router 模板和组件模板之间感到困惑。
    • mmmh 我想这是一个非常相关的问题,显然我有 "angular": "^1.5.2", "angular-ui-router": "^0.3.1" 翻译成 0.3。 2安装。我会尝试 ui-router 1.0 alpha 版。现在。
    • 其实我现在很困惑。有 angular-ui-router && ui-router。我猜一个是另一个成角度的叉子。如果你有什么建议我会采纳的。最适合与角度组件一起使用。
    • @Olivvv angular-ui-router
    • 我建议使用组件而不是控制器,我不同意 Eric Elliot 在这种情况下的引用。故意使用已弃用的概念,因为“这种方式更容易,工作量更少”也被称为 懒惰
    【解决方案2】:

    您的状态提供者将如下所示

    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>  
    

    参考multiple views

    【讨论】:

    • 如前所述,我专门要求提供组件架构。组件也有模板。
    • 所以你也可以在那里添加
    【解决方案3】:
    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'
      })
    

    除了我们的 cmets,您还可以使用类似上述的方法。这很冗长,但那是 Angular 1.5。尚未测试它是否有效,但它是可能如何工作的基本概念。

    主要的收获是您拥有route1 组件,该组件仅处理链接路由内容(如 url、resolves 等)并将该信息传递给其子项(其中没有任何子项)。

    routeView1 只是渲染路由的工作方式,并使用require 与一些共享的父 API 通信(如果需要,您也可以为此使用单向绑定,但是这会导致很多方法到一个凌乱的模板)。

    sharedBehaviour 仅包含您希望呈现的任何子传递给它的共享行为。


    诚然相当混乱,我会更喜欢你改为使用route-view-1的单向绑定并处理shared-behaviour中的链接,但这可能是相当多的重复。你可以使用一些嵌入魔法来解决这个问题,但这……并不值得。

    我会真的建议不要像其他回答者建议的那样共享控制器。在 Angular 2 及更高版本中,控制器 组件。您可以通过执行与我所做的类似的事情(或通过使用带有回调的单向绑定)和使用组合来共享行为。


    顺便说一句,正如我在回答中提到的,较新版本的 UI-Router for Angular 1.5 允许您指定要呈现的组件而不是模板。请参阅here 了解更多信息。

    【讨论】:

    • 我正在研究你的答案。 “较新版本”是指“1.0.0-rc.1”,对吗? github.com/angular-ui/ui-router/releases
    • 我是否理解正确,您建议使用单独的“读取”、“创建”、“更新”组件?
    • 我建议您使用一个组件来显示每条路线。如果你愿意,你可以拥有一个包含所有共享行为的组件,尽管你描述得越多,听起来你就越想要一个处理 CRUD 操作的服务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多