如何从已更新的父母列表中更新子组件 [英] How to update child components from the updated list of parents

查看:77
本文介绍了如何从已更新的父母列表中更新子组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Angular的新手,当前使用的是1.6版.

I'm new to Angular and currently using version 1.6.

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

I'm implementing the component style of Angular. I just want to ask what's the best way to communicate from parent to child components? I know there is an existing question but I have a specific scenario (I'm not sure if it's unique or not).

这是场景:

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

Modal -> create new todo -> Parent ( update the object ) -> personal todo ( update the list )

  1. 我有一个创建待办事项的模式.
  2. 然后,在创建新的待办事项之后,将值传递给父项,以更新待办事项的对象.
  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;
    }
  }

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

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

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

My question again is how I can pass the updated data after I create to the child component which is in charge of displaying the todo list?

已更新

<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>

推荐答案

如何通过父母的更改来更新子组件

使用单向绑定<

  • <<attr-在本地范围属性和通过属性attr传递的表达式之间建立单向(单向)绑定.该表达式是在父作用域的上下文中求值的.如果未指定attr名称,则假定属性名称与本地名称相同.您还可以通过添加?:<?<?attr使绑定成为可选.
  • < or <attr - set up a one-way (one-directional) binding between a local scope property and an expression passed via the attribute attr. The expression is evaluated in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. You can also make the binding optional by adding ?: <? or <?attr.

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

For example, given <my-component my-attr="parentModel"> and directive definition of scope: { localModel:'<myAttr' }, then the isolated scope property localModel will reflect the value of parentModel on the parent scope. Any changes to parentModel will be reflected in localModel, but changes in localModel will not reflect in parentModel.

- AngularJS全面指令API参考-范围

$onChanges生命周期挂钩:

  • $onChanges(changesObj)-每当单向绑定更新时调用. changesObj是一个哈希,其键是已更改的绑定属性的名称,而值是格式为{ currentValue, previousValue, isFirstChange() }的对象.使用此挂钩可触发组件中的更新.
  • $onChanges(changesObj) - Called whenever one-way bindings are updated. The changesObj is a hash whose keys are the names of the bound properties that have changed, and the values are an object of the form { currentValue, previousValue, isFirstChange() }. Use this hook to trigger updates within a component.

AngularJS开发人员指南-组件


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

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


With object content — Use the $doCheck Life-cycle Hook

When binding an object or array reference, the $onChanges hook only executes when the value of the reference changes. To check for changes to the contents of the object or array, use the $doCheck life-cycle hook:

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

从文档中:

控制器可以提供以下用作生命周期挂钩的方法:

The controller can provide the following methods that act as life-cycle hooks:

  • $doCheck()-在摘要循环的每一回合调用.提供机会来检测更改并采取措施.您希望对检测到的更改做出响应的任何操作都必须从此挂钩中调用;实现此功能对$onChanges的调用时间没有影响.例如,如果您希望执行深层相等性检查或检查Date对象,而Angular的变更检测器无法检测到该更改,并且因此不会触发,则此钩子可能很有用. $onChanges..该钩子不带任何参数调用;如果检测到更改,则必须存储以前的值以供比较与当前值.
  • $doCheck() - Called on each turn of the digest cycle. Provides an opportunity to detect and act on changes. Any actions that you wish to take in response to the changes that you detect must be invoked from this hook; implementing this has no effect on when $onChanges is called. For example, this hook could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not be detected by Angular's change detector and thus not trigger $onChanges. This hook is invoked with no arguments; if detecting changes, you must store the previous value(s) for comparison to the current values.

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

有关更多信息,

  • AngularJS angular.equals API Reference
  • AngularJs 1.5 - Component does not support Watchers, what is the work around?

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>
    `,
})

<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
    <parent-component>
    </parent-component>
<body>

有关更多信息,请参见

  • AngularJS Developer Guide - Component-based application architecture
  • AngularJS Comprehensive API Reference - scope

这篇关于如何从已更新的父母列表中更新子组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆