AngularJS/UI-Router: 如何将一个控制器与多个命名视图一起使用?

AngularJS/UI-Router: How do I use one controller with multiple named views?

我有一个 child 状态,它在 parent 状态(header,内容)中填充命名视图。然而,它们都共享相同的数据,我不想制作冗余的第二个控制器,但似乎这是我唯一的选择之一。我可以只使用一个视图,但它会包含太多看起来很乱的标记。

我阅读了文档 here,他们展示的示例是该州的每个视图都有自己的控制器。

这不适合我的场景。例如,ui-router 表示我必须这样做:

.state('root.profile', {
    url: '@:slug',
    views: {
        'header': {
            templateUrl: 'app/profile/profile-header.html',
            controller: 'ProfileHeaderController as profileHeader'
        },
        'content': {
            templateUrl: 'app/profile/profile-body.html',
            controller: 'ProfileBodyController as profileBody'
        }
    }
});

.. 我更愿意这样做:

.state('root.profile', {
    url: '@:slug',
    views: {
        'header': {
            templateUrl: 'app/profile/profile-header.html'
        },
        'content': {
            templateUrl: 'app/profile/profile-body.html'
        }
    },
    controller: 'ProfileController as profile'
});

第二个选项对我来说效果更好,因为正如我所说,它们共享相同的数据,我宁愿不重复大量相同的逻辑,但不幸的是它不起作用。

我已经在为一个控制器使用一项服务。我不想创建另一个服务来存储一组值以在两个控制器中使用,因为它仍然不是真正的 DRY。

有这样的work-around吗?

考虑到您的代码示例,我不明白这个说法是错误的:"they share the same data and I would rather not reproduce a lot of the same logic twice"

1) 它们共享相同的数据:既然你有一个服务,我假设该服务存储当前数据状态,这意味着控制器确实共享相同的数据。

2) 而不是重复大量相同的逻辑两次:您的视图引用了相同的控制器,但实例不同,这意味着您不必重现任何逻辑。

"I am already using a service for the one controller. I wouldn't want to have to create another service just to store one set of values to use in both controllers"。 如果您将该服务设为工厂,即单例,则相同的实例将传递给使用 factory-service 的每个控制器。

但是,我看到了一种可能的解决方案,您可以使用它来解析数据并将控制器定义为配置文件状态的父级。这是通过在 rootroot.profile 状态之间设置另一个状态。在下面的示例中,两个视图(profile-body.htmlprofile-header.html)现在可以使用 ProfileController.

的相同实例
.state('root', { .. })
.state('root.profile', {
    abstract:true,
    controller:'ProfileController as profile',
    resolve: {
       profile:function(yourProfileDataService) {
           //Resolve profile data
       }
    }
})
.state('root.profile.view', {
    url: '@:slug',
    views: {
        'header': {
            templateUrl: 'app/profile/profile-header.html'
        },
        'content': {
            templateUrl: 'app/profile/profile-body.html'
        }
    }
});

如示例所示,我还建议使用 resolve 属性,它在实例化控制器之前解析数据,然后将其注入到控制器中。 Resolve docs.