【问题标题】:Re-render AngularJS template重新渲染 AngularJS 模板
【发布时间】:2019-11-19 12:54:28
【问题描述】:

我希望这样的问题会被回答一百万次,但找不到任何适合我的特定问题的东西。我的组件如下所示:

const todoApp = () => ({
  template: `
    <div>
      <todo-list todos="todoApp._filteredTodos"></todo-list>
    </div>
  `,
  controller: class {
    constructor(todoService) {
      [...]
    }

    updateState() {
      this._activeTodos = _.filter(this._todos, t => !t.completed);

      switch (this.selectedFilter) {
        case 'active':
          this._filteredTodos = _.filter(this._todos, t => !t.completed);
          break;
        case 'completed':
          this._filteredTodos = _.filter(this._todos, t => t.completed);
          break;
        default:
          this._filteredTodos = this._todos;
      }
    },

    updateTodos() {
      this._todos = this.todoService.fetch();
      this.updateState();
    }

    [...]
  },
  restrict: 'E',
  bindToController: true,
  controllerAs: 'todoApp',
  link: function(scope, elem, attr, ctrl) {
    document.addEventListener('store-update', ctrl.updateTodos.bind(ctrl), false);
  }
});

export default todoApp;

我需要更新todoApp._todos,以便&lt;todo-list&gt; 使用新的项目集进行更新。这不会在 atm 发生。

&lt;todo-list&gt; 组件非常简单:

const todoList = () => ({
  scope: {
    todos: '=',
  },
  template: `
    <ul class="todo-list">
      <li ng-repeat="todo in todoList.todos track by todo.id">
        [...]
      </li>
    </ul>
  `,
  controller: class {
    [...]
  },
  restrict: 'E',
  bindToController: true,
  controllerAs: 'todoList'
});

export default todoList;

我在这里错过了什么?

【问题讨论】:

  • 什么触发了updateState()函数?
  • 这是一个很好的问题,@georgeawg。我已经用呼叫发起者-updateTodos () 更新了示例。反过来,updateTodos() 是自定义事件的事件处理程序。
  • 自定义事件如何与AngularJS框架及其摘要循环集成?只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。
  • 这是组件的link@georgeawg 中的简单addEventListener。我已经更新了这个例子。我还能将该事件集成到 AngularJS 执行上下文中吗?

标签: angularjs templates binding


【解决方案1】:

错误

link: function(scope, elem, attr, ctrl) {
    document.addEventListener('store-update', ctrl.updateTodos.bind(ctrl), false);
}

AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 拆分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。

您也可以使用$apply() 从 JavaScript 进入 AngularJS 执行上下文。请记住,在大多数地方(控制器、服务)$apply 已经被处理事件的指令调用。 只有在实现自定义事件回调时,或使用第三方库回调时,才需要显式调用 $apply。

link: function(scope, elem, attr, ctrl) {
    document.addEventListener('store-update',storeUpdateHandler, false);
    scope.$on("$destroy", function() {
        document.removeEventListener('store-update',storeUpdateHandler);
    });

    function storeUpdateHandler() {
        scope.$apply(ctrl.updateTodos.bind(ctrl));
    }
}

同样为了避免内存泄漏,当指令的作用域被销毁时,代码应该移除事件监听器。

有关详细信息,请参阅

【讨论】:

  • 非常感谢@georgeawg 的详细解释。尽管不时抛出Error: [$rootScope:inprog] $apply already in progress,但它工作正常。我已经玩过$apply(只是在处理程序的函数本身中)并让它工作,但你的回答可以更好地看待这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 2015-05-21
  • 1970-01-01
  • 2015-03-17
  • 2013-09-02
  • 2014-01-16
  • 1970-01-01
相关资源
最近更新 更多