有没有办法在Angular 2中动态插入一个组件作为DOM标记的子(而不是兄弟)?
有很多例子可以将动态组件作为给定ViewContainerRef标签的兄弟插入,例如(从RC3开始):
@Component({
selector: '...',
template: '<div #placeholder></div>'
})
export class SomeComponent {
@ViewChild('placeholder', {read: ViewContainerRef}) placeholder;
constructor(private componentResolver: ComponentResolver) {}
ngAfterViewInit() {
this.componentResolver.resolveComponent(MyDynamicComponent).then((factory) => {
this.componentRef = this.placeholder.createComponent(factory);
});
}
}
Run Code Online (Sandbox Code Playgroud)
但这会生成类似于以下内容的DOM:
<div></div>
<my-dynamic-component></my-dynamic-component>
Run Code Online (Sandbox Code Playgroud)
预期结果:
<div>
<my-dynamic-component></my-dynamic-component>
</div>
Run Code Online (Sandbox Code Playgroud)
使用SomeComponent's ViewContainerRef具有相同的结果,它仍然将生成的组件插入为兄弟,而不是孩子.我可以使用一个解决方案,其中模板为空,动态组件插入模板中(在组件选择器标签内).
当使用像ng2-dragula这样的库从动态组件列表中拖动并从模型更新中受益时,DOM结构非常重要.额外的div位于可拖动元素的列表中,但在模型之外,打破了拖放逻辑.
有人说这是不可能的(参见此评论),但这听起来像是一个非常令人惊讶的限制.
已经回答了如何从Angular 2组件中获取DOM元素:( ComponentRef.location.nativeElementComponentRef.location提供了可以直接访问DOM的ElementRef).
但是如何做相反的事情,即当我只有原生DOM对象时获取对ComponentRef的引用?
当我尝试使用interact.js拖放Angular 2组件时就是这种情况.该库使用回调函数来通知拖动哪个元素,以及我们尝试删除哪个元素.event提供了一个对象,我发现的唯一有用信息是DOM元素(target属性).
例:
interact('my-component-tag').draggable({
// ...
onstart: function (event:any) {
var dom = event.target; // ref to the <my-component-tag> tag
// How to find the Angular ComponentRef object here?
}
// ...
}).dropzone({
// ...
ondragenter: function (event:any) {
var targetDom = event.relatedTarget; // targeted <my-component-tag> tag
// Same question here,
// to identify where we want to insert the dragged element.
}
// ...
});
Run Code Online (Sandbox Code Playgroud)
你可以检查处理程序src/Interactjs.ts.打开控制台以查看关联的日志并将组件拖放到另一个组件上.我有DOM的元素信息,但我想要Angular组件,比如说访问 …
有没有办法从一个EventEmitter(或Angular 2 alpha 46/RxJS 5 alpha中可用的等效物)获得热观察?即,如果我们在值解析后进行订阅,则会使用先前解析的值触发.与我们总是返回相同承诺时的情况类似.
理想情况下,只使用Angular 2对象(我稍后会在某处读取轻量级RxJS以删除依赖项),否则导入RxJS就可以了.AsyncSubject似乎符合我的需要,但在RxJS 5 alpha中不可用.
我尝试了以下,没有成功(从不触发).有关如何使用它的任何想法?
let emitter = new EventEmitter<MyObj>();
setTimeout(() => {emitter.next(new MyObj());});
this.observable = emitter;
return this.observable.share();
Run Code Online (Sandbox Code Playgroud)
用例:只访问一些异步对象(例如,一系列HTTP调用合并/包装在新的中EventEmitter),但将已解析的异步对象提供给订阅它的任何服务/组件,即使它们在解析后订阅(HTTP)收到回复).
编辑:问题不是关于如何合并HTTP响应,而是如何从EventEmitter或任何等效的Angular 2 alpha 46/RxJS 5 alpha获得(hot?)observable,允许在检索/解析异步结果后进行订阅(HTTP只是异步原点的一个例子).myEventEmitter.share()不工作(以上CF plunker),虽然它与可观察到通过HTTP(CF返回工作从plunker @Eric马丁内斯).从Angular 2 alpha 46开始,.toRx()方法不再存在,EventEmitter是observable和subject本身.
只要我们总是返回相同的promise对象,这对promises来说效果很好.由于我们有观察者介绍了HTTP Angular 2服务,我想避免混合使用promises和观察者(据说观察者比promises更强大,因此它应该允许使用promise进行简单的操作).
有关share()的规范(我没有找到版本5 alpha的文档 - Angular 2使用的版本) - 处理Observable由Angular 2 HTTP服务返回的,而不是在EventEmitter上工作.
编辑:澄清为什么不使用HTTP返回的Observable,并补充说不直接使用RxJS会更好.
编辑:更改说明:关注的是多个订阅,而不是合并HTTP结果.
谢谢!