表行中的AngularJS UI路由器嵌套状态视图(内联编辑)
从事AngularJS+UI路由器项目。获得了具有以下(此处简化)要求的任务:表行中的AngularJS UI路由器嵌套状态视图(内联编辑),angularjs,angular-ui-router,Angularjs,Angular Ui Router,从事AngularJS+UI路由器项目。获得了具有以下(此处简化)要求的任务: 使用表格行末尾的Edit按钮显示表格中的项目列表 单击Edit按钮应将表格行转换为项目编辑表单(内联编辑) 项目列表和项目编辑视图应可通过url访问 因此,我定义了我的状态: // app.js $stateProvider .state("list", { url: "/", component: "listComponent" }) .st
- 使用表格行末尾的
按钮显示表格中的项目列表Edit
- 单击
按钮应将表格行转换为项目编辑表单(内联编辑)Edit
- 项目列表和项目编辑视图应可通过url访问
// app.js
$stateProvider
.state("list", {
url: "/",
component: "listComponent"
})
.state("list.edit", {
url: "/{id}/edit",
component: "editComponent"
});
}
ListComponent
模板如下所示:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th> </th>
</tr>
<!-- Hide this row when NOT in edit mode -->
<tr ng-repeat-start="item in $ctrl.items" ng-if="$ctrl.editIndex !== $index">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>
<button type="button" ng-click="$ctrl.onEditClick($index, item.id)">Edit</button>
</td>
</tr>
<!-- Show this row when in edit mode -->
<tr ng-repeat-end ng-if="$ctrl.editIndex === $index">
<td colspan="3">
<ui-view></ui-view>
</td>
</tr>
</table>
问题:
当我在使用EditComponent
时,我注意到它会启动http请求两次。几小时后,我想出了这样的EditComponent
,显示了实际发生的情况:
function EditController() {
// random number per component instance
this.controllerId = Math.floor(Math.random() * 100);
this.$onInit = function() {
console.log("INIT:", this.controllerId);
};
this.$onDestroy = function() {
console.log("DESTROY:", this.controllerId);
};
}
控制台显示此输出:
DESTROY: 98
INIT: 80
DESTROY: 80
INIT: 9
第二次单击编辑时,此输出显示
在我们离开它时被销毁(预期)EditComponent#98
- 创建并立即销毁
(意外的)EditComponent#80
是在我们现在“编辑”新项目时创建的(预期)EditComponent#9
s加上ng如果s打得不好,但我不知道如何解决这个问题
我尝试过的一件事是,我在ListComponent
中创建了一个
,并通过纯javascript在ui路由器状态更改上移动它。但这并没有起作用,因为我很快就开始从ui路由器的框架中发现与缺少HTML节点有关的错误
问题:
我做错了什么?我认为angular的摘要周期(以及相关的DOM更改)比ui路由器开始转换和相关组件的创建和销毁要晚,这可能是创建并快速销毁EditComponent#80
的原因。但我不知道如何解决这个问题
下面是一个代码笔,显示正在发生的事情:
(别忘了打开开发者控制台,看看发生了什么)
谢谢假设您正在从索引2切换到索引3。我认为这可能是正在发生的事情:
function EditController() {
// random number per component instance
this.controllerId = Math.floor(Math.random() * 100);
this.$onInit = function() {
console.log("INIT:", this.controllerId);
};
this.$onDestroy = function() {
console.log("DESTROY:", this.controllerId);
};
}
索引2处的ui视图当前处于活动状态。在单击处理程序中,您调用state.go,索引2处的ui视图短暂接收更新的状态参数id:3
。然后,当ng if生效并创建索引3处的ui视图时,它将被销毁
更改代码,使其首先破坏索引2处的ui视图。添加超时,以便调用state.go在下一个摘要周期中显示第二个ui视图
this.onEditClick = function(index, id) {
this.editIndex = null;
$timeout(() => {
this.editIndex = index;
$state.go("list.edit", { id: id });
});
};