如何从更新的父项列表更新子组件

Pep*_*mat 3 angularjs angular-components

我是Angular的新手,目前正在使用1.6版本.

我正在实现Angular的组件样式.我只是想问一下从父组件到子组件进行通信的最佳方式是什么?我知道存在一个问题,但我有一个特定的场景(我不确定它是否是唯一的).

这是场景:

模态 - >创建新待办事项 - >父(更新对象) - >个人待办事项(更新列表)

  1. 我有一个创建待办事项的模式.
  2. 然后在创建新的todo之后传递父对象的值以更新todo的对象.
  3. 当我更新todo的父列表传递给个人todo组件以更新视图上的列表.
  angular.module('tab')
    .controller('TabController', TabController);

  function TabController() {
    let vm = this;
    let updatedTodoObject = {};

    vm.$onInit = function () {
      vm.personalTodo = vm.todo.own_todo;
      vm.externalTodo = vm.todo.external_todo;
    }

    vm.$onChanges = function (changes) {
      console.log('I\'m triggered');
    }

    vm.updateTodoList  = updateTodoList;

   function updateTodoList( result ) {
    updatedTodoObject = angular.copy(vm.todo);
    updatedProjectObject.user_todos.push(result)
    if( vm.todo !== updatedTodoObject) {
     vm.todo = updatedTodoObject;
    } else {
     console.log("Still in reference");
    }
   }

    vm.getUpdatedTodotList = function( ) {
      return vm.todo;
    }
  }
Run Code Online (Sandbox Code Playgroud)
angular.module('...')
    .component('...', {
      bindings: {
        onResultTodoUpdated: '&'
      },
      controllerAs: 'todo',
      controller: ['TodoService', '$log', '$state', function(TodoService, $log, $state) {
        let vm = this;
        let todo = {};

        vm.newTodoModal = function() {
          TodoService.newTodoModal()
            .then(function (TodoName) {
              TodoService.createTodo(TodoName)
                .then(function(response) {
                  if( response.status === 201 ) {

                    todo = {
                      ...
                      ...
                    }

                    vm.onResultTodoUpdated( { result: todo } );
                  }
                })
                .catch(function(error) {
                  console.log(error);
                });
Run Code Online (Sandbox Code Playgroud)
  angular.module('...')
    .component('...', {
      bindings: {
        todos: "<"
      },
      controllerAs: 'personal',
      controller: function(){
        let vm = this;
        vm.isShowTodoArchived = false;

        vm.$onInit = function () {
          getWatchedTodo();
        }

        function getWatchedTodo () {
         vm.todos = vm.todos;
         vm.todosSize = vm.todos.length;
        }
Run Code Online (Sandbox Code Playgroud)

我的问题是我在创建负责显示待办事项列表的子组件后如何传递更新的数据?

更新

<div class="tab-pane active" id="todosTab">
  <nv-new-todo on-result-todo-updated="todo.updateTodoList(result)"></nv-new-project>

  <div class="my-todos">
    <nv-personal-todo todos="todo.personalTodo" ></nv-personal-todo>
    <nv-external-todo todos="todo.externalTodo"></nv-external-todo>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

geo*_*awg 9

如何使用父项更改来更新子组件

使用单向绑定<

  • <<attr- 在本地范围属性和通过该属性传递的表达式之间设置单向(单向)绑定attr.表达式在父作用域的上下文中计算.如果未指定attr名称,则假定属性名称与本地名称相同.您还可以通过添加?:<?或来使绑定可选<?attr.

例如,给定<my-component my-attr="parentModel">和指令定义scope: { localModel:'<myAttr' },则隔离的范围属性localModel将反映parentModel父范围的值.任何更改parentModel都将反映在内localModel,但更改localModel不会反映出来parentModel.

- AngularJS综合指令API参考 - 范围

$onChanges生命周期钩子:

  • $onChanges(changesObj) - 每当更新单向绑定时调用.它changesObj是一个哈希,其键是已更改的绑定属性的名称,值是表单的对象{ currentValue, previousValue, isFirstChange() }.使用此挂钩可触发组件内的更新.

- AngularJS开发人员指南 - 组件


使用对象内容 - 使用$doCheck生命周期挂钩

绑定对象或数组引用时,$onChanges挂钩仅在引用更改时执行.要检查对象或数组内容的更改,请使用$doCheck生命周期钩子:

app.component('nvPersonalTodo', {
  bindings: {
    todos: "<"
  },
  controller: function(){
    var vm = this;
    this.$doCheck = function () {
      var oldTodos;
      if (!angular.equals(oldTodos, vm.todos)) {
        oldTodos = angular.copy(vm.todos);
        console.log("new content");          
        //more code here
      };
    }
})
Run Code Online (Sandbox Code Playgroud)

来自Docs:

控制器可以提供以下充当生命周期钩子的方法:

  • $doCheck() - 在摘要周期的每个回合调用.提供检测和处理更改的机会.必须从此挂钩调用您希望采取的任何响应您检测到的更改的操作; 实现这一点对$onChanges调用何时没有影响.例如,如果您希望执行深度相等检查或检查Date对象,则此挂钩可能很有用,Angular的更改检测器无法检测到这些更改,因此不会触发$onChanges.这个钩子没有参数调用; 如果检测到更改,则必须存储先前的值以与当前值进行比较.

- AngularJS综合指令API参考 - 生命周期钩子

欲获得更多信息,


简单的演示

angular.module("app",[])
.component("parentComponent", {
    template: `
        <fieldset>
            Inside parent component<br>
            parentData={{$ctrl.parentData}}
            <child-component in-data="$ctrl.parentData"></child-component>
        </fieldset>
    `,
    controller: function () {
        this.$onInit = () => {
            this.parentData = 'test'
        };
    },
})
.component("childComponent",{
    bindings: {
        inData: '<',
    },
    template: `
        <fieldset>Inside child component<br>
            inData={{$ctrl.inData}}
        </fieldset>
    `,
})
Run Code Online (Sandbox Code Playgroud)
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
    <parent-component>
    </parent-component>
<body>
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅