AngularJS UI-table 行中的路由器嵌套状态视图(内联编辑)

AngularJS UI-Router nested state view in table row (inline edit)

正在处理 AngularJS + UI-Router 项目。得到了这些(此处简化)的任务要求ui评论:

所以我定义了我的状态:

// 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>&nbsp;</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 时,此输出显示

这只是告诉我很多 <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 });
  });
};

https://codepen.io/christopherthielen/project/editor/ZyNpmv