2017-04-08 157 views
-1

是的,这已问了几次 - 随意合并问题 - 但我可能是一个拉默。我在页面中有两个组件,如下所示:将数据从一个角度组件传递到另一个角度组件

<post-list></post-list> 
<post-detail><post-detail> 

这是一个非常简单的主细节页面。当用户单击post-list列表中的某个项目时,post-detail将加载所选帖子并显示它。

问题是如何获得从post-listpost-detail的值以使其立即作出反应?我认为在post-detail等待更改应该有一个Observable。我也假设它应该观看输入属性。问题是:我可以从post-list获得一个值并将其作为输入属性发送到post-detail?可以(也应该)通过父组件传递它,还是应该为此定义一个服务?

+3

因为你提到Observable,我们可以假设这是一个关于angular2的问题,并且与angularjs无关? – Claies

+0

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service – echonax

+0

是的,Angular 2,更确切地说是Angular 4.感谢您的链接。 –

回答

2

一种方法是从@Input和@Output装饰器。你的父组件应该处理传入和传出子组件的内容。

<post-list 
    (itemSelected)="loadDetails(any)"> 
</post-list> 
<post-detail 
    [selectedItem]="any"> 
<post-detail> 

itemSelected - >是一个输出,其是从列表组件到父组件被选择最新发射的EventEmitter。

loadDetails(any) - >这是父组件中的一个方法,它处理由list组件发出的whats,做什么,你从孩子得到什么。

selectedItem - >是详细组件中的输入属性,它可以是任何类型的应用,理想情况下应该从loadDetails接收结构。

这只是一个简单的模板,可以满足您的要求。 但是也可以写一个服务来处理这个问题。

0

您可以按照:

1-注入$ rootScope到这两个部件的

2-实现下面的代码,其中一个作为数据接收器:

$rootScope.$on('transferDataEvent', function(data) { 

    }); 

3-拨打以下代码作为数据发送者

$rootScope.$emit('transferDataEvent', data); // send data 

$使听者和 $发出通过作用域层级向上调度事件

+0

这是AngularJS,不是Angular,但无论如何感谢。不幸的是,还没有问题的Angular 4标签。 –

1

的问题是我怎么从列表后的值到后期的细节,使其立即作出反应?我假设应该有一个Observable在后期细节等待变化。我也假设它应该观看输入属性。问题是:我可以从列表中获取值并将其作为输入属性发送给后期详细信息?可以(也应该)通过父组件传递它,还是应该为此定义一个服务?

这种情况非常简单 - 后期列表需要指示何时选择某个项目,并将该“selectedItem”信息传递给后期细节以供显示。

如果我正在处理这种情况,我会使用简单的输入和输出(即属性和事件绑定)在组件之间传递信息,使用父组件作为通信的中介。您正在通过父组件进行路由 - 具体来说,后期列表指示何时选择帖子以及该帖子是什么,而帖子详细信息仅显示传递给它的任何帖子。

因此,后列表需要一个名为itemSelect的@Output EventEmitter属性或其他适当的东西。此属性的目的是通知任何关心何时选择项目以及该项目是什么的人。

PostListComponent:

export class PostDetailComponent { 
    ..... 
    @Output() postSelect = new EventEmitter(); 

    // whenever a post is selected, you call this.postSelect.emit(selectedPost) 
    // to notify others which post is selected 

在PostDetailComponent:

export class PostDetailComponent { 
    ..... 
    // this is your property binding 
    // used to get data in real time in to the component for display 
    @Input() post; 

最后,父组件需要交物业接收来自列表发布更新,并通过这些更新后期细节。

为父级

的为父级只是监听来自PostList更新,并接收他们,分配事件(在模板中的$事件值),其内部岗位性质,实质这又被推送到PostDetail。

@Component({ 
    ....... 
    template: ` 
     <post-list (postSelect)="post = $event"> </post-list> 
     <post-detail [post]="post"> </post-detail> 
    ` 
}) 
export class ParentComponent { 
    post: any; // brokers the communication between the two child components 
    ....... 

这就是我的情况。

您可以使用服务来代理通信,但通常只有当通信方式复杂或两个组件在视图层次结构中彼此不接近时才需要,因此很难从一个组件到另一个。但在你的情况下,服务可能是矫枉过正的。

See the docs for more info.

+0

谢谢。这正是我想到的,并在此期间实施。我不确定这是否违背了一些最佳做法或任何不成文的规定。这是Angular的难点,而不是它背后的逻辑。 –

0

一种更简单的方法,您的问题是使用模板引用变量:https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ref-vars

我建议,因为你的组件是兄弟姐妹,即。共享同一个家长。

您可以在模板中引用post-list成分是这样的:

看看这个plnkr我设置:https://plnkr.co/edit/C7kjlaZItfn0sE12HNMO?p=preview

这里是代码:

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 
     <post-list #postList></post-list> 
     <post-detail [text]="postList?.chosen?.detail"></post-detail> 
    </div> 
    `, 
}) 
export class App { 
    name:string; 
    constructor() { 
    this.name = `Angular! v${VERSION.full}` 
    } 
} 


@Component({ 
    selector: 'post-detail', 
    template: ` 
    <div> 
     <h2>{{text}}</h2> 
    </div> 
    `, 
}) 
export class PostDetail { 
    @Input() text: string; 
    constructor() { 
    } 
} 


@Component({ 
    selector: 'post-list', 
    template: ` 
    <div> 
     <ul> 
     <li *ngFor="let post of posts; let i = index"> 
     <button (click)="chosen = posts[i]">{{post.title}}</button> 
     </li> 
     </ul> 
    </div> 
    `, 
}) 
export class PostList { 
    chosen: any; 
    posts: [] = 
    [ 
    { title:"post 1", detail:"post one detail" }, 
    { title:"post 2", detail:"post two detail" }, 
    { title:"post 3", detail:"post three detail" }, 
    ] 
    constructor() { 
    } 
} 
相关问题