首页 > 解决方案 > 重新渲染 AngularJS 模板

问题描述

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

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,以便<todo-list>使用新的项目集进行更新。这不会发生在atm。

<todo-list>组件非常简单:

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;

我在这里想念什么?

标签: angularjstemplatesbinding

解决方案


错误

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));
    }
}

同样为了避免内存泄漏,当指令的范围被破坏时,代码应该删除事件监听器。

有关详细信息,请参阅


推荐阅读