Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
yyLee0522 opened this issue May 16, 2017 · 11 comments
Open

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

yyLee0522 opened this issue May 16, 2017 · 11 comments

Comments

@yyLee0522
Copy link

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

@KiddZZ
Copy link

KiddZZ commented May 18, 2017

同问

@hstarorg
Copy link

document.querySelector

@yyLee0522
Copy link
Author

yyLee0522 commented May 18, 2017

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

@Adol1111
Copy link

为什么要这样做,不是应该写一个服务,让顶部导航栏订阅,然后点击按钮的时候推送一个值来控制导航栏的展示吗。具体可以看一下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
Copy link

KiddZZ commented May 31, 2017

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

@wut1
Copy link

wut1 commented Jul 12, 2017

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

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

@Adol1111
Copy link

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

@hstarorg
Copy link

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

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

@Adol1111
Copy link

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

@hstarorg
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants