AngularJs:如何将部分数据从一个组件传递到另一个组件 [英] AngularJs: How to pass part of my data from one component to another

查看:73
本文介绍了AngularJs:如何将部分数据从一个组件传递到另一个组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个角度控件,用于显示一组数据,大致类似于以下示例.除了唯一的块外,它还具有许多重复的(但离散的)相同结构的块.

I have an angular control that I use to display a set of data looking roughly like the following example. Apart from a unique block, it has a number of repeating (but discrete) blocks of the same structure.

{
  "person": {
    "lastName": "Bettertester",
    "firstName": "Fester",
    "address": "Out in the woods 17",
    "zipCode": "10666",
    "place": "Back of beyond"
  },
  "contact1": {
    "firstName": "Jane",
    "lastName": "Doe",
    "phone": "555-987-654",
    "relationship": "Aunt"
  },
  "contact2": {
    "firstName": "Kherumple",
    "lastName": "Whaduffle",
    "phone": "555-666-000",
    "relationship": "Imaginary friend"
  },
  "contact3": {
    "firstName": "Kherumple",
    "lastName": "Whaduffle",
    "phone": "555-666-000",
    "relationship": "Imaginary friend"
  }
}

我已经编写了angularjs组件来检索和显示此结构,但希望将重复的块交给另一个组件.

I have written an angularjs component to retrieve and display this structure but want to hand the repeating block off to another component.

angular.module('myModule').component('mainComponent', {
  templateUrl : 'person.template.html',
  controller : [ '$scope', '$http', function mainController($scope, $http) {
    var self = this;
    self.data = null;
    $http.get(url).then(function(response) {
      self.data = response.data;
    }, function(response, status) {
      console.warn("Error while loading data");
      console.warn(" - response=", response);
      console.warn(" - status=", status);
      self.data = null;
    });
  } ]
});

相应的模板:

<div>
  <h1>Person information</h1>
  <table>
  <tr>
    <th class="label-column">First & last name</th>
    <td class="data">{{$ctrl.data.person.firstName}} {{$ctrl.data.person.lastName}}</td>
  </tr>
  <tr>
    <th class="label-column">Address</th>
    <td class="data">{{$ctrl.data.person.address}}</td>
  </tr>
  <tr>
    <th class="label-column">ZIP code & Place</th>
    <td class="data">{{$ctrl.data.person.zipCode}} {{$ctrl.data.person.place}}</td>
  </tr>
  </table>

  <contact details="{{$ctrl.data.contact1}}"></contact> <!-- passing the details like this sort of works -->
  <contact details="{{$ctrl.data.contact2}}"></contact>
  <contact details="$ctrl.data.contact3"></contact>     <!-- passing the details like this does not work at all -->
</div>

联系人详细信息的控制器如下:

The controller for the contact details looks as follows:

angular.module('myModule').component('contact', {
  templateUrl : 'contact.template.html',
  bindings : {
    details : '@'
  },
  controller : [ '$scope', '$http', function contactController($scope, $http) {
    var self = this;
    console.log("- details=", self.details);
  } ]
});

以及相应的模板:

<div>
  <h2>Contact</h2>
  <table>
  <!-- this works -->
  <tr>
    <th class="label-column">Everything</th>
    <td class="data">{{$ctrl.details}}</td>
  </tr>
  <tr>
    <th class="label-column">First & last name</th>
    <td class="data">{{$ctrl.details.firstName}} {{$ctrl.details.lastName}}</td>
  </tr>
  <tr>
    <th class="label-column">Phone</th>
    <td class="data">{{$ctrl.details.phone}}</td>
  </tr>
  <tr>
    <th class="label-column">Relationship</th>
    <td class="data">{{$ctrl.details.relationship}}</td>
  </tr>
  </table>

  <contact details="{{$ctrl.data.contact1}}"></contact>
  <contact details="{{$ctrl.data.contact2}}"></contact>
  <contact details="{{$ctrl.data.contact3}}"></contact>
  <contact details="{{$ctrl.data.contact4}}"></contact>
</div>

我的问题是如何以一种允许我访问相应模板中其字段的方式,正确地将mainComponent的详细联系信息传递给contactComponent.如果我不带花括号将它们传递,则contact组件似乎根本无法获取任何数据.如果我用花括号传递它们,则contact组件似乎以某种方式获取它们,但是不像我无法访问contact块中的字段那样,不是正确的json对象.我确定我错过了一些琐碎的事情,但没有设法找出我要去哪里.

My questions is how to correctly pass the contact details that are part of the mainComponent to the contactComponent in a way that lets me access its fields in the corresponding template. If I pass them without the curly braces, the contact component does not seem to get any data at all. If I pass them with the curly braces, the contact component seems to get them in a way, but not as correct json object as I am unable to access fields within the contact block. I'm sure I'm missing something trivial but did not manage to find out where I go wrong.

推荐答案

  1. 使用单向< 绑定而不是插值 @ 绑定因为 @ 会监视插值,如果没有插值,则只需将原始属性字符串作为值本身传递即可.< = 绑定监视表达式更改,并相应地使用表达式值更新模板.在这种特殊情况下,< = 更方便,因为我们只需要监视组件的输入更改,就不需要通过更改来影响父级的其他监视相同的表达式.

  1. Use one-way < binding instead of interpolation @ binding because @ watches for interpolation and if there is no interpolation just passes the raw attribute string as the value itself. < or = binding watches for expression change and updates the template with the expression value correspondingly. In this particular case < is more convenient than = because we only need to watch input changes for component, we don't need that additional watch to affect parent back by changing the same expression.

应用< 后,请安全使用没有大括号的属性值.

After applying < use attribute values without curly braces safely.

$ onInit 控制器生命周期挂钩中初始化您的组件逻辑,因为在初始化绑定之后会调用此挂钩,这正是您 console.log的确切原因(-details =",this.details); contact 控制器中给出了-details = undefined .

Initialise your component logic in $onInit controller lifecycle hook, because this hook is called after the bindings have been initialised, which was the exact cause of why your console.log("- details=", this.details); was giving - details=undefined in contact controller.

代码详细信息:

let app = angular.module('app', []);

app.component('mainComponent', {
  template: `
  <div>
  <h1>Person information</h1>
  <table>
  <tr>
    <th class="label-column">First & last name</th>
    <td class="data">{{$ctrl.data.person.firstName}} {{$ctrl.data.person.lastName}}</td>
  </tr>
  <tr>
    <th class="label-column">Address</th>
    <td class="data">{{$ctrl.data.person.address}}</td>
  </tr>
  <tr>
    <th class="label-column">ZIP code & Place</th>
    <td class="data">{{$ctrl.data.person.zipCode}} {{$ctrl.data.person.place}}</td>
  </tr>
  </table>

  <contact details="$ctrl.data.contact1"></contact> <!-- passing the details like this sort of works -->
  <contact details="$ctrl.data.contact2"></contact>
  <contact details="$ctrl.data.contact3"></contact>     <!-- passing the details like this does not work at all -->
</div>
  `,
  controller: ['$scope', '$http', function mainController($scope, $http) {
  
    var self = this;
    
    self.$onInit = () => {
      self.data = {
        "person": {
          "lastName": "Bettertester",
          "firstName": "Fester",
          "address": "Out in the woods 17",
          "zipCode": "10666",
          "place": "Back of beyond"
        },
        "contact1": {
          "firstName": "Jane",
          "lastName": "Doe",
          "phone": "555-987-654",
          "relationship": "Aunt"
        },
        "contact2": {
          "firstName": "Kherumple",
          "lastName": "Whaduffle",
          "phone": "555-666-000",
          "relationship": "Imaginary friend"
        },
        "contact3": {
          "firstName": "Kherumple",
          "lastName": "Whaduffle",
          "phone": "555-666-000",
          "relationship": "Imaginary friend"
        }
      };
    };
    
  }]
});

app.component('contact', {
  template: `
    <div>
  <h2>Contact</h2>
  <table>
  <!-- this works -->
  <tr>
    <th class="label-column">Everything</th>
    <td class="data">{{$ctrl.details}}</td>
  </tr>
  <tr>
    <th class="label-column">First & last name</th>
    <td class="data">{{$ctrl.details.firstName}} {{$ctrl.details.lastName}}</td>
  </tr>
  <tr>
    <th class="label-column">Phone</th>
    <td class="data">{{$ctrl.details.phone}}</td>
  </tr>
  <tr>
    <th class="label-column">Relationship</th>
    <td class="data">{{$ctrl.details.relationship}}</td>
  </tr>
  </table>
</div>
  `,
  bindings: {
    details: '<'
  },
  controller: ['$scope', '$http', function jassMonitorHandController($scope, $http) {
    this.$onInit = () => {
      console.log("- details=", this.details);
    };
  }]
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>

<div ng-app="app">
    <main-component></main-component>
</div>

这篇关于AngularJs:如何将部分数据从一个组件传递到另一个组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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