Angular 2 Component - Access DOM(或者创建没有模板的Component,纯粹来自JS)
Angular 2 Component - Access DOM (or create Component without template, purely from JS)
尝试在这里玩 Angular 2...了解到它仍处于 alpha 阶段。
如何从组件访问 DOM 元素?具体来说,我想使用 d3 等其他库从代码生成自定义 DOM。我想我需要创建一个组件并以某种方式插入组件生命周期以使用 d3 改变 DOM...知道从哪里开始挖掘吗?
我正在使用这个 quickstart repo。
谢谢!
此文档 (http://victorsavkin.com/post/118372404541/the-core-concepts-of-angular-2) mentions 'decorator-style directives' which I believe are described with a little more detail and basic example here (https://angular.io/api/core/Directive)。
如果您不介意使用 Directive 而不是 Component,那很简单。对于打字稿中的 Angular 2.0.0-alpha.33,您可以使用 D3 通过注入 ElementRef:
来操纵 DOM
@Directive({
selector: 'scatter-plot',
lifecycle: [LifecycleEvent.onChange],
properties: [ 'data' ]
})
export class ScatterPlot {
root: Selection<any>;
data: Array<ScatterPlotDataPoint>;
x: (number) => number;
y: (number) => number;
defaultSize: string;
circles: any;
constructor(
@Inject(ElementRef) elementRef: ElementRef,
@Attribute('height') height: string,
@Attribute('default-size') defaultSize: string
) {
var el:HTMLElement = elementRef.nativeElement;
this.root = d3.select(el);
this.defaultSize = defaultSize ? defaultSize : "5";
this.circles = this.root
.append('svg')
.attr('class', 'chart')
.style({
'width': '100%',
'height': height ? height + 'px': '',
}).
selectAll('circle');
}
render(newValue) {
if (!newValue) return;
this.x = d3.scale.linear().domain([-10, 110]).range([0, 250]);
this.y = d3.scale.linear().domain([-10, 110]).range([100, 0]);
this.circles = this.circles
.data(newValue);
this.circles.exit().remove();
this.circles.enter()
.append('circle');
this.circles
.transition()
.attr("r", d => d.size ? d.size: this.defaultSize)
.style("fill", d => d.color)
.attr('cx', d => this.x(d.x))
.attr('cy', d => this.y(d.y));
}
onChange() {
this.render(this.data);
}
}
注意:[已弃用]
您可以使用"BrowserDomAdapter"
https://angular.io/docs/ts/latest/api/platform/browser/BrowserDomAdapter-class.html
import {BrowserDomAdapter} from 'angular2/platform/browser'
@Component({
selector: 'dom',
templateUrl: 'path/to/template.html',
providers: [BrowserDomAdapter]
})
export class DomComponent {
constructor(private _dom: BrowserDomAdapter) {
var domIWant = this._dom.query('whatever you want to get');
}
}
进程
- 导入 BrowserDomAdapter
- 应用提供商:[BrowserDomAdapter]
- 在构造函数中启动()
- 使用实例化的 BrowserDomAdapter
获取 dom
使用元素引用
ElementRef 会将当前的 DOM 节点注入到您的组件中。 ElementRef 服务将始终是您当前 DOM 节点的本地服务。
注入后,您可以使用 nativeElement 获取实际的 DOM 节点:
var el = elementRef.nativeElement
一旦你有了这个,你可以用任何你喜欢的方式来操作它,要么使用 DOM 脚本,要么使用像 jQuery:[=13= 这样的 DOM 包装器]
$(el)
.append('<p>Some interesting Stuff')
.addClass('my_class');
但如果可以的话,请不要这样做
请注意,与 Angular 1 一样,不鼓励使用直接 DOM 操作。您几乎可以使用模板完成所有工作,大多数时候您应该喜欢这种工作方式。
直接 DOM 操作导致代码复杂、难以理解、难以测试。
虽然有时它似乎是最好的解决方案。例如,如果您必须与第三方、高度复杂的框架(如图形库)集成。
这是一个有效的例子(在 ES6 中)
var AppComponent = ng.core
.Component({
selector: "app",
template:
`
<div>Captured element</div>
`
})
.Class({
constructor: [ng.core.ElementRef, function(elementRef) {
var el = elementRef.nativeElement
el;
}]
})
正如其他张贴者所提到的:您可以通过将 ElementRef
注入指令来操纵 DOM。但是,请仔细考虑您是否真的需要这样做。
D3 是一个 DOM 操纵工具。它允许您将数据对象绑定到 DOM 节点,然后从该元素添加或删除子元素以响应更改的数据值。这几乎正是 Angular 2 所做的。
当然,D3 还做其他事情。您可以为饼图或正态分布生成角度,您可能希望为此使用 D3。
我知道这不是您要找的答案。这不是我要找的答案,但是...仔细考虑是否需要使用 D3 进行 DOM 操作和数据绑定。 Angular 2 已经有 DOM 操作和数据绑定。
尝试在这里玩 Angular 2...了解到它仍处于 alpha 阶段。
如何从组件访问 DOM 元素?具体来说,我想使用 d3 等其他库从代码生成自定义 DOM。我想我需要创建一个组件并以某种方式插入组件生命周期以使用 d3 改变 DOM...知道从哪里开始挖掘吗?
我正在使用这个 quickstart repo。
谢谢!
此文档 (http://victorsavkin.com/post/118372404541/the-core-concepts-of-angular-2) mentions 'decorator-style directives' which I believe are described with a little more detail and basic example here (https://angular.io/api/core/Directive)。
如果您不介意使用 Directive 而不是 Component,那很简单。对于打字稿中的 Angular 2.0.0-alpha.33,您可以使用 D3 通过注入 ElementRef:
来操纵 DOM@Directive({
selector: 'scatter-plot',
lifecycle: [LifecycleEvent.onChange],
properties: [ 'data' ]
})
export class ScatterPlot {
root: Selection<any>;
data: Array<ScatterPlotDataPoint>;
x: (number) => number;
y: (number) => number;
defaultSize: string;
circles: any;
constructor(
@Inject(ElementRef) elementRef: ElementRef,
@Attribute('height') height: string,
@Attribute('default-size') defaultSize: string
) {
var el:HTMLElement = elementRef.nativeElement;
this.root = d3.select(el);
this.defaultSize = defaultSize ? defaultSize : "5";
this.circles = this.root
.append('svg')
.attr('class', 'chart')
.style({
'width': '100%',
'height': height ? height + 'px': '',
}).
selectAll('circle');
}
render(newValue) {
if (!newValue) return;
this.x = d3.scale.linear().domain([-10, 110]).range([0, 250]);
this.y = d3.scale.linear().domain([-10, 110]).range([100, 0]);
this.circles = this.circles
.data(newValue);
this.circles.exit().remove();
this.circles.enter()
.append('circle');
this.circles
.transition()
.attr("r", d => d.size ? d.size: this.defaultSize)
.style("fill", d => d.color)
.attr('cx', d => this.x(d.x))
.attr('cy', d => this.y(d.y));
}
onChange() {
this.render(this.data);
}
}
注意:[已弃用]
您可以使用"BrowserDomAdapter"
https://angular.io/docs/ts/latest/api/platform/browser/BrowserDomAdapter-class.html
import {BrowserDomAdapter} from 'angular2/platform/browser'
@Component({
selector: 'dom',
templateUrl: 'path/to/template.html',
providers: [BrowserDomAdapter]
})
export class DomComponent {
constructor(private _dom: BrowserDomAdapter) {
var domIWant = this._dom.query('whatever you want to get');
}
}
进程
- 导入 BrowserDomAdapter
- 应用提供商:[BrowserDomAdapter]
- 在构造函数中启动()
- 使用实例化的 BrowserDomAdapter 获取 dom
使用元素引用
ElementRef 会将当前的 DOM 节点注入到您的组件中。 ElementRef 服务将始终是您当前 DOM 节点的本地服务。
注入后,您可以使用 nativeElement 获取实际的 DOM 节点:
var el = elementRef.nativeElement
一旦你有了这个,你可以用任何你喜欢的方式来操作它,要么使用 DOM 脚本,要么使用像 jQuery:[=13= 这样的 DOM 包装器]
$(el)
.append('<p>Some interesting Stuff')
.addClass('my_class');
但如果可以的话,请不要这样做
请注意,与 Angular 1 一样,不鼓励使用直接 DOM 操作。您几乎可以使用模板完成所有工作,大多数时候您应该喜欢这种工作方式。
直接 DOM 操作导致代码复杂、难以理解、难以测试。
虽然有时它似乎是最好的解决方案。例如,如果您必须与第三方、高度复杂的框架(如图形库)集成。
这是一个有效的例子(在 ES6 中)
var AppComponent = ng.core
.Component({
selector: "app",
template:
`
<div>Captured element</div>
`
})
.Class({
constructor: [ng.core.ElementRef, function(elementRef) {
var el = elementRef.nativeElement
el;
}]
})
正如其他张贴者所提到的:您可以通过将 ElementRef
注入指令来操纵 DOM。但是,请仔细考虑您是否真的需要这样做。
D3 是一个 DOM 操纵工具。它允许您将数据对象绑定到 DOM 节点,然后从该元素添加或删除子元素以响应更改的数据值。这几乎正是 Angular 2 所做的。
当然,D3 还做其他事情。您可以为饼图或正态分布生成角度,您可能希望为此使用 D3。
我知道这不是您要找的答案。这不是我要找的答案,但是...仔细考虑是否需要使用 D3 进行 DOM 操作和数据绑定。 Angular 2 已经有 DOM 操作和数据绑定。