Angular 구성 요소 템플릿에 스크립트 태그 추가
Angular2 제거<script>템플릿에서 태그를 자동으로 지정하여 사용자가 이 기능을 "가난한 사람" 로더로 사용하지 못하도록 합니다.
여기서 문제는 현재 스크립트 태그가 코드나 다른 스크립트 파일을 로드하는 것보다 더 많은 용도를 가지고 있다는 것입니다.주변에 추가 기능이 있을 가능성이 있습니다.<script>태그는 미래에도 도입될 것입니다.
현재 사용되는 JSON-LD는 다음과 같은 형식을 사용합니다.
<script type="application/ld+json">
{
"@context":"http://schema.org",
"@type":"HealthClub",
...
}
</script>
일반적으로 제안되는 해결 방법은 다음을 통해 동적으로 스크립트 태그를 문서에 추가하는 것입니다.ngAfterViewInit후크, 하지만 이것은 분명히 적절한 ng2 연습이 아니며 JSON-LD가 할 수 있어야 하는 서버 측면에서 작동하지 않을 것입니다.
다음과 같은 다른 해결 방법이 있습니까?<script>각진 2 템플릿의 태그(브라우저 내에서 태그가 비활성화되어 있더라도) 또는 프레임워크가 지나치게 의견을 제시하는 경우입니까?이 상황이 angular2로 해결되지 않는다면 어떤 다른 해결책이 존재할 수 있습니까?
여기서 파티에 조금 늦었을 수도 있지만 위의 답변은 Angular SSR(예: Angular SSR)에서 잘 작동하지 않기 때문입니다.document is not defined서버측 또는document.createElement is not a function), 저는 Angular 4+에 사용할 수 있는 버전을 서버와 브라우저 모두에서 작성하기로 결정했습니다.
구성 요소 구현
import { Renderer2, OnInit, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
class MyComponent implements OnInit {
constructor(
private _renderer2: Renderer2,
@Inject(DOCUMENT) private _document: Document
) { }
public ngOnInit() {
let script = this._renderer2.createElement('script');
script.type = `application/ld+json`;
script.text = `
{
"@context": "https://schema.org"
/* your schema.org microdata goes here */
}
`;
this._renderer2.appendChild(this._document.body, script);
}
}
서비스 구현
참고: 서비스를 사용할 수 없습니다.Renderer2직접적으로.사실 요소 렌더링은 구성요소에서 수행해야 합니다.그러나 JSON-LD 생성을 자동화해야 하는 상황이 발생할 수 있습니다.script페이지의 태그예를 들어, 경로 탐색 변경 이벤트에서 이러한 기능을 호출하는 상황이 발생할 수 있습니다.그래서 저는 다음에서 작동하는 버전을 추가하기로 결정했습니다.Service맥락.
import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
/**
* Use a Service to automate creation of JSON-LD Microdata.
*/
class MyService {
constructor(
@Inject(DOCUMENT) private _document: Document
) { }
/**
* Set JSON-LD Microdata on the Document Body.
*
* @param renderer2 The Angular Renderer
* @param data The data for the JSON-LD script
* @returns Void
*/
public setJsonLd(renderer2: Renderer2, data: any): void {
let script = renderer2.createElement('script');
script.type = 'application/ld+json';
script.text = `${JSON.stringify(data)}`;
renderer2.appendChild(this._document.body, script);
}
}
템플릿에 스크립트 태그를 추가하는 Angular2 방법은 없습니다.
사용.require(...)구성 요소 클래스에서 외부 스크립트를 로드하는 것이 해결 방법으로 언급되었습니다(직접 시도하지는 않음).
스크립트 태그를 동적으로 추가하려면 사용
constructor(private elementRef:ElementRef) {};
ngAfterViewInit() {
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://somedomain.com/somescript";
this.elementRef.nativeElement.appendChild(s);
}
참고 항목각2: 구성 요소에 타사 js 스크립트 포함
다음은 Angular 5.2.7과 함께 작동합니다.
필요한 가져오기는 다음과 같습니다.
import { Inject, AfterViewInit, ElementRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
사후 뷰 구현시작:
export class HeroesComponent implements AfterViewInit {
구성 요소가 둘 이상의 인터페이스를 구현하는 경우 쉼표로 구분합니다. 예:
export class HeroesComponent implements OnInit, AfterViewInit {
생성자에게 다음 인수를 전달합니다.
constructor(@Inject(DOCUMENT) private document, private elementRef: ElementRef) { }
다음 보기에 추가수명 주기 보기의 초기 방법:
ngAfterViewInit() {
const s = this.document.createElement('script');
s.type = 'text/javascript';
s.src = '//external.script.com/script.js';
const __this = this; //to store the current instance to call
//afterScriptAdded function on onload event of
//script.
s.onload = function () { __this.afterScriptAdded(); };
this.elementRef.nativeElement.appendChild(s);
}
Script 뒤에 추가 멤버 기능 추가.
이 함수는 외부 스크립트가 성공적으로 로드된 후에 호출됩니다.따라서 외부 js에서 사용하고자 하는 속성이나 함수는 이 함수의 본문에서 액세스됩니다.
afterScriptAdded() {
const params= {
width: '350px',
height: '420px',
};
if (typeof (window['functionFromExternalScript']) === 'function') {
window['functionFromExternalScript'](params);
}
}
사실 템플릿에 스크립트 태그를 추가하는 Angular2 방법은 없습니다.하지만 당신은 우선 당신이 가져올 어떤 속임수를 할 수 있습니다.AfterViewInit그리고.ElementRef과 같이로부터: 음과같로각이터2부다:
import {Component,AfterViewInit,ElementRef} from 'Angular2/core';
그러면 당신은 그것들을 당신의 반에서 그렇게 실행할 것입니다:
export class example1 implements AfterViewInit{}
그리고 여기 당신이 할 매우 간단한 자바스크립트 돔 트릭이 있습니다.
export class example1 implements AfterViewInit{
ngAfterViewInit()
{
var s=document.createElement("script");
s.type="text/javascript";
s.innerHTML="console.log('done');"; //inline script
s.src="path/test.js"; //external script
}
}
const head = document.getElementsByTagName('head')[0];
const _js = document.createElement('script');
_js.type = 'text/javascript';
_js.appendChild(document.createTextNode('{your js code here}'));
head.appendChild(_js);
이것은 원하는 곳 어디에나 배치할 수 있고 좋은 접근법입니다.
나는 다음 방법으로 구성 요소 내부의 조건을 사용하여 동적으로 로드하는 js 스크립트를 라이프 훅에 추가했습니다.
private loadChatWithScript() {
let chatScript = document.createElement("script");
chatScript.type = "text/javascript";
chatScript.async = true;
chatScript.src = "https://chat-assets.frontapp.com/v1/chat.bundle.js";
document.body.appendChild(chatScript);
let chatScriptConfiguration = document.createElement("script");
chatScriptConfiguration.type = "text/javascript";
chatScriptConfiguration.async = true;
chatScriptConfiguration.innerHTML = "window.FCSP = 'some-key-123'";
document.body.appendChild(chatScriptConfiguration);
}
신사 숙녀 여러분, 한 번 보세요.
픽셀 스크립트를 추가하면 시간을 절약할 수 있습니다. 이 솔루션은 정교함보다 쉽습니다.
첫 번째 로드된 페이지에서만 작동 -
» index.htmlAngular 프로젝트 내에서 다음과 같은 것으로 조정합니다(스크립트 태그에 스크립트를 넣으십시오).
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Angular Application</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script>
// Put your script here
alert('Test me, Angular hero!');
</script>
</body>
</html>
각진 구성요소 템플릿 내에서 스크립트를 사용하는 경우, 저는 @Nicky의 답변을 제안합니다.
언급URL : https://stackoverflow.com/questions/38088996/adding-script-tags-in-angular-component-template
'programing' 카테고리의 다른 글
| SQL Server 2016, 잘못된 개체 이름 'STRING_SPLIT' (0) | 2023.08.16 |
|---|---|
| Swift에서 배열 [String] 슬라이싱 반환 유형이 [String]이 아닌 것 같습니다. (0) | 2023.08.16 |
| JQuery를 통한 노란색 페이드 효과 (0) | 2023.08.16 |
| 간단한 조인으로 MySQL/MariaDB COUNT(*) 행 속도가 매우 느림 (0) | 2023.08.16 |
| 데이터베이스에서 테이블의 마지막 업데이트 시간 가져오기 (0) | 2023.08.16 |