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 的每个控制器。
但是,我看到了一种可能的解决方案,您可以使用它来解析数据并将控制器定义为配置文件状态的父级。这是通过在 root
和 root.profile
状态之间设置另一个状态。在下面的示例中,两个视图(profile-body.html
和 profile-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.
我有一个 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 的每个控制器。
但是,我看到了一种可能的解决方案,您可以使用它来解析数据并将控制器定义为配置文件状态的父级。这是通过在 root
和 root.profile
状态之间设置另一个状态。在下面的示例中,两个视图(profile-body.html
和 profile-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.