Angular 2 Компонент - доступ к DOM (или создание компонента без шаблона, исключительно из JS)
Попытка играть с Angular 2 здесь... поняла, что она все еще в альфе.
Как мне получить доступ к элементам DOM из Component? В частности, я хотел бы использовать другие библиотеки, такие как d3 для создания пользовательского DOM из кода. Полагаю, мне нужно создать компонент и как-то подключить к жизненному циклу компонента, чтобы изменить DOM с d3... любую идею, с которой начать копать?
Я использую этот быстрый старт.
Спасибо!
Ответы
Ответ 1
Если вы не против использования Директивы вместо Компонента, это просто. Для Angular 2.0.0-alpha.33 в typescript вы можете использовать D3 для управления DOM путем инъекции ElementRef:
@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);
}
}
Ответ 2
Использовать ElementRef
ElementRef будет вставлять текущий DOM node в ваш компонент. Служба ElementRef всегда будет локальной для вашего текущего DOM node.
Введя его, вы можете получить фактический DOM node с помощью nativeElement:
var el = elementRef.nativeElement
Как только вы это сделаете, вы можете манипулировать им так, как вам нравится, используя DOM-скриптинг или используя DOM-обертку, такую как jQuery:
$(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;
}]
})
Ответ 3
Примечание. [Устаревший]
Вы можете использовать "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');
}
}
Процесс
- import BrowserDomAdapter
- применить поставщиков: [BrowserDomAdapter]
- инициировать в конструкторе()
- получить dom с помощью instanced BrowserDomAdapter
Ответ 4
Этот документ (http://victorsavkin.com/post/118372404541/the-core-concepts-of-angular-2) упоминает "директивы стиля декоратора", которые, как я полагаю, описаны более подробно и базовым примером здесь (https://angular.io/api/core/Directive).
Ответ 5
Как упоминались другие плакаты: вы можете манипулировать DOM, введя ElementRef
в директиву. Однако тщательно подумайте, действительно ли вам нужно это делать.
D3 - инструмент манипуляции DOM. Он позволяет привязывать объект данных к DOM node, а затем добавлять или удалять дочерние элементы из этого элемента в ответ на изменение значений данных. Это в значительной степени то, что делает Angular 2.
Конечно, D3 делает и другие вещи. Например, вы можете генерировать углы для круговой диаграммы или обычного распределения, и вы можете использовать D3 для этого.
Я знаю, что это не тот ответ, который вы ищете. Это не тот ответ, который я искал, но... Подумайте, нужно ли использовать D3 для манипуляций с DOM и привязки данных. Angular 2 уже имеет DOM-манипуляцию и привязку данных.