这个问题似乎过于含糊,但我想不出更好的方式来描述这个想法,所以我会试着详细解释一下。
我将MasterController附加到我的SPA应用程序的<html>
标记。此MasterController包含用于控制以下UI元素的所有逻辑和模型:
<title>
标记)Show filters
,Export data to Excel
和Add new record
。虽然可以通过检测当前的ui-router状态(通过其$stateChangeSuccess
事件)来管理此列表中的前两项,但最后两项(用户名和按钮)有些问题,尤其是按钮。 / p>
我可以使用$broadcast
管理按钮操作,因此可以通知每个控制器有关任何按钮的点击。但这里棘手的部分是按钮可能需要不同的组合 - 一个页面可能需要所有这些按钮,另一个页面可能不需要。
让我们说,ui-router加载一些CustomersController。此时MasterController接收$stateChangeSuccess
事件,默认情况下会隐藏所有按钮。
但是现在,CustomersController如何告诉MasterController,CustomersController从一开始就需要两个特定的按钮?
理论上,我可以使用CustomersController中的$emit
向MasterController发送一个事件,但它感觉很难看。事件是指事件,而不是发送请求,例如“嘿,MasterController,如果你在某个范围内的某个地方,你可以请出示以下按钮吗?”。
当然,我可能错了,也许有一些方法可以使用Angular事件系统以干净的方式管理这个场景。
我想到的是,也许在$stateChangeSuccess
事件中,我可以以某种方式检测我的按钮点击事件当前是否有任何监听器,然后我可以隐藏没有连接任何监听器的按钮,但是我我不确定该怎么做,而且我不确定它是否能按预期工作 - 当ui-router用另一个控制器重新创建视图时,是否会分离旧的侦听器。
答案 0 :(得分:1)
如果您只是嵌套控制器,其相应的范围实际上使用原型继承。因此,您可以在MasterController中定义函数$scope.configureButtons
,并从嵌套的CustomerController中的$scope
调用此函数。
如果控制器没有嵌套,您可能需要求助于$rootScope.$broadcast
来设置按钮。
答案 1 :(得分:0)
今天我根据@DiegoCastañoChillarón的回答得到了一个棘手的想法。我想 - 但是有可能使用ui-router来交换现有视图的控制器并且还会重新绑定$ scope吗?我是否仍然可以替换加载视图的内部部分?
事实证明它是可行的!现在我不必控制主控件中的公共视图片段,我也不需要继承或复制它们 - 我只需通过ui-router将控制器切换到所需的控制器。像这样:
$stateProvider
.state("customers", {
url: "^/customers",
views: {
"controller": {
controller: "CustomerController as cntrlr"
},
"page@customers": // <- this is important, absolute name required for ui-router to find nested view
{
templateUrl: "customers"
}
}
}) // other routes follow in the same manner
我的HTML看起来像这样:
<div id="routes-root" ui-view="controller">
<div id="content-header-buttons">
<button type="button" ng-click="master.toggleFilter()">Filter data</button>
<button type="button" ng-click="cntrlr.exportClicked()">Export</button>
<button type="button" ng-click="cntrlr.createNewClicked()">Create</button>
</div>
<div id="view-content" ui-view="page"></div>
</div>
如您所见,我离开主控制器仅控制过滤器块的可见性,这不会改变。
但是控制器本身附加到#routes-root
元素,保留了内部内容,而ui-router(或Angular)足够聪明,可以将$ scope和cntrlr
变量附加到已加载的控制器。然后我将内部视图加载到#view-content
,它也会附加到已经加载的控制器上。