AngularJS UI-table 行中的路由器嵌套状态视图(内联编辑)
AngularJS UI-Router nested state view in table row (inline edit)
正在处理 AngularJS + UI-Router 项目。得到了这些(此处简化)的任务要求ui评论:
- 在 table 行末尾使用
Edit
按钮显示 table 中的项目列表
- 单击
Edit
按钮应将 table 行变成项目编辑表单(内联编辑)
- 项目列表和项目编辑视图应该可以通过 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>
以及 ListComponent
本身的主要部分:
function ListController($state) {
this.editIndex = null;
this.items = [
{ id: 1, name: "Y-Solowarm" },
// ...
{ id: 10, name: "Keylex" }
];
this.onEditClick = function(index, id) {
this.editIndex = index;
$state.go("list.edit", { id: id });
};
}
问题:
当我在 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
第二次单击 Edit
时,此输出显示
EditComponent#98
在我们离开它时被摧毁(预期)
EditComponent#80
创建并立即销毁(意外)
EditComponent#9
是我们现在创建的 'editing' 新项目(预期)
这只是告诉我很多 <ui-view>
和 ng-if
一起玩起来不是很好,但我不知道如何解决这个问题。
我尝试过的一件事是我在 ListComponent
中创建了一个 <ui-view>
并在 ui 上移动它 - 通过纯 javascript 路由器状态更改.但这没有用,因为我很快就开始从 ui-router 的框架中收到与丢失 HTML 节点相关的错误。
问题:
我在这里做错了什么?我认为 angular 的摘要周期(以及相关的 DOM 更改)结束时间晚于 ui-路由器开始转换和相关组件的创建和销毁,这可能是 [=26 的原因=] 被创建并且 quickly 被销毁。但我不知道如何解决这个问题。
这是一个显示正在发生的事情的代码笔:
https://codepen.io/ramunsk/project/editor/AYyYqd
(别忘了打开开发者控制台看看发生了什么)
谢谢
假设您要从索引 2 切换到索引 3。我认为这可能是正在发生的事情:
索引 2 处的 ui-视图当前处于活动状态。在您调用 state.go 的点击处理程序中,索引 2 处的 ui-视图会短暂接收更新后的状态参数 id: 3
。然后当 ng-if 生效并创建索引 3 处的 ui-view 时它被销毁。
更改您的代码,使其破坏索引 2 第一个 处的 ui-视图。添加超时,以便它调用 state.go 在 下一个摘要周期 .
中显示第二个 ui-视图
this.onEditClick = function(index, id) {
this.editIndex = null;
$timeout(() => {
this.editIndex = index;
$state.go("list.edit", { id: id });
});
};
正在处理 AngularJS + UI-Router 项目。得到了这些(此处简化)的任务要求ui评论:
- 在 table 行末尾使用
Edit
按钮显示 table 中的项目列表 - 单击
Edit
按钮应将 table 行变成项目编辑表单(内联编辑) - 项目列表和项目编辑视图应该可以通过 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>
以及 ListComponent
本身的主要部分:
function ListController($state) {
this.editIndex = null;
this.items = [
{ id: 1, name: "Y-Solowarm" },
// ...
{ id: 10, name: "Keylex" }
];
this.onEditClick = function(index, id) {
this.editIndex = index;
$state.go("list.edit", { id: id });
};
}
问题:
当我在 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
第二次单击 Edit
时,此输出显示
EditComponent#98
在我们离开它时被摧毁(预期)EditComponent#80
创建并立即销毁(意外)EditComponent#9
是我们现在创建的 'editing' 新项目(预期)
这只是告诉我很多 <ui-view>
和 ng-if
一起玩起来不是很好,但我不知道如何解决这个问题。
我尝试过的一件事是我在 ListComponent
中创建了一个 <ui-view>
并在 ui 上移动它 - 通过纯 javascript 路由器状态更改.但这没有用,因为我很快就开始从 ui-router 的框架中收到与丢失 HTML 节点相关的错误。
问题:
我在这里做错了什么?我认为 angular 的摘要周期(以及相关的 DOM 更改)结束时间晚于 ui-路由器开始转换和相关组件的创建和销毁,这可能是 [=26 的原因=] 被创建并且 quickly 被销毁。但我不知道如何解决这个问题。
这是一个显示正在发生的事情的代码笔:
https://codepen.io/ramunsk/project/editor/AYyYqd
(别忘了打开开发者控制台看看发生了什么)
谢谢
假设您要从索引 2 切换到索引 3。我认为这可能是正在发生的事情:
索引 2 处的 ui-视图当前处于活动状态。在您调用 state.go 的点击处理程序中,索引 2 处的 ui-视图会短暂接收更新后的状态参数 id: 3
。然后当 ng-if 生效并创建索引 3 处的 ui-view 时它被销毁。
更改您的代码,使其破坏索引 2 第一个 处的 ui-视图。添加超时,以便它调用 state.go 在 下一个摘要周期 .
中显示第二个 ui-视图this.onEditClick = function(index, id) {
this.editIndex = null;
$timeout(() => {
this.editIndex = index;
$state.go("list.edit", { id: id });
});
};