kittencup / angular2-ama-cn

angular2 随便问
692 stars 101 forks source link

如何在组件内获取外部的html元素 #257

Open yyLee0522 opened 7 years ago

yyLee0522 commented 7 years ago

现在的情况是,我需要在某个组件中点击某个按钮,就隐藏页面顶部的导航栏,但这个导航栏是在顶层组件里面的,我如何在子组件中去获取导航栏的element呢? 我考虑过用Output,传递事件到导航栏所在的组件(假设是app.component)中去处理,但是这样的话我需要从app.component开始往下一层一层地接收来自子组件output传递出来的事件,可能有3,4层都说不定,非常麻烦。 所以有其他简便的方法吗?

KiddZZ commented 7 years ago

同问

hstarorg commented 7 years ago

document.querySelector

yyLee0522 commented 7 years ago

@hstarorg But it's not an Angular's way

Adol1111 commented 7 years ago

为什么要这样做,不是应该写一个服务,让顶部导航栏订阅,然后点击按钮的时候推送一个值来控制导航栏的展示吗。具体可以看一下rxjs,这就是为什么ng要引入rxjs的原因。

简单的例子

let bSubject = new BehaviorSubject("a"); 

bSubject.subscribe((value) => {
  console.log("Subscription got", value); 
});

bSubject.next("b");
bSubject.next("c"); 
bSubject.next("d");
KiddZZ commented 7 years ago

用service能解决组件和路由组件之间的通信问题

wut1 commented 7 years ago

import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject';

@Injectable() export class GlobalState {

private _data = new Subject(); private _dataStream$ = this._data.asObservable();

private _subscriptions: Map<string, Array> = new Map<string, Array>();

constructor() { this._dataStream$.subscribe((data) => this._onEvent(data)); }

notifyDataChanged(event, value) { let current = this._data[event]; if (current !== value) { this._data[event] = value;

  this._data.next({
    event: event,
    data: this._data[event]
  });
}

}

subscribe(event: string, callback: Function) { let subscribers = this._subscriptions.get(event) || []; subscribers.push(callback);

this._subscriptions.set(event, subscribers);

}

_onEvent(data: any) { let subscribers = this._subscriptions.get(data['event']) || [];

subscribers.forEach((callback) => {
  callback.call(null, data['data']);
});

} }

hstarorg commented 7 years ago

@yyLee0522 不要太死板,有些地方用原生JS也没问题。另外,这个需求,可以考虑使用EventBus。

Adol1111 commented 7 years ago

@hstarorg 虽然是这么说,但是建议还是仅仅针对组件本身或关联比较密切的组件使用这种方式修改。如果在另一个毫无关联的组件中去通过未暴露的接口强行修改这个组件,往往会让项目变得非常混乱,容易引入一些莫名其妙的bug。况且针对这个问题,ng是提供了解决方案的,并非一定要使用这种特殊手段。

hstarorg commented 7 years ago

@Adol1111 如果是组件,最好不要使用这种做法。但如果是页面,特别是layout页面,用这种方式完全没问题。

对于问题本身,我个人会选择从Page中使用EventBus。

Adol1111 commented 7 years ago

@hstarorg 基本同意,不过ng已经整合了rxjs,不需要再额外引入EventBus。当然刚接触rx的人还是比较难上手的,需要花点时间去理解

hstarorg commented 7 years ago

@Adol1111 ,基于rxjs封装全局EventBus。这比单独使用要易用很多。