AngularJS/UI路由器:如何使用一个具有多个命名视图的控制器

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

本文关键字:控制器 视图 一个 路由器 UI 何使用 AngularJS      更新时间:2023-09-26

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

我阅读了这里的文档,他们展示的例子是,状态中的每个视图都有自己的控制器。

这对我的场景来说并不理想。例如,ui路由器说我必须这样做:

.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。

像这样的事情有什么解决办法吗?

考虑到您的代码示例,我不认为这句话是错误的:"它们共享相同的数据,我宁愿不重复两次相同的逻辑"

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

2) 不要两次复制很多相同的逻辑:您的视图引用的是同一个控制器,但引用的是不同的实例,这意味着您不必复制任何逻辑。

"我已经为一个控制器使用了一个服务。我不想仅仅为了存储一组值来在两个控制器中使用而创建另一个服务"。如果您将该服务作为一个工厂,它是一个单例,那么同一个实例将传递给使用工厂服务的每个控制器。

然而,我看到了一个可能的解决方案,您可以解析数据并将控制器定义为配置文件状态的父级。这是通过在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属性,该属性在实例化控制器之前解析数据,然后将其注入控制器。解决文档。