【问题标题】:Angular 12.1 add html element using typescriptAngular 12.1 使用打字稿添加 html 元素
【发布时间】:2021-09-07 17:18:05
【问题描述】:

我正在通过 youtube 学习 Angular,但我正在尝试做一些新的事情,但我遇到了一个错误,我的代码附在下面,请帮帮我。

我想像 div.setAttribute('(click)',"popUp($event)"); 这样设置属性,但我出错了。

TypeScript

export class AppComponent {
    createEl(){
      console.time("timer");
      for (let i = 0; i < 10; i++) {
        let div = document.createElement("div");
        div.textContent = `Hello, World! ${i}`;
        div.setAttribute('(click)',"popUp($event)");
        document.getElementById('divEl')?.appendChild(div);
      };
      console.timeEnd("timer");
}

HTML

<div id="divEl"></div>
<button (click)="createEl()">click me</button>

错误

【问题讨论】:

    标签: javascript angular typescript


    【解决方案1】:

    这并不是真正有角度的做事方式。尽量避免对document.createElement等文档进行操作。

    实现这一点的更好方法是定义模板中重复元素的外观并从数组中驱动它。这样我们就可以保持模板进行显示,打字稿进行处理,而 Angular 处理这两者之间的一切。

    HTML

    <div id="divEl">
      <div *ngFor="let row of rows; index as i;" (click)="popUp($event)">
        Hello, World! {{i}}
      </div>
    </div>
    
    <button (click)="createEl()">click me</button>
    

    打字稿

    export class AppComponent {
      rows: unknown[] = [];
      createEl():void {
        this.rows.push('something');
      }
    
      popUp(event:Event):void {}
    }  
    

    更多关于循环的阅读:https://angular.io/api/common/NgForOf

    【讨论】:

    • 什么需要更多时间,执行时间或代码编写?无论哪种方式,这是以角度构建模板更新的适当方式
    • 在 Angular 中仍然是合适的方法。是的,在这个例子中执行时间可能会更慢,但是当你开始使用其他 Angular 模板功能时,开销不会增加。
    • 要改进这个答案(这是使用框架的正确方法),您可以使用trackBy 函数来提高 ngFor 渲染性能。喜欢这个*ngFor="let row of rows; index as i; trackBy: myTrackBy”。然后在 TS 中做:myTrackBy(item, index:number) { return item.idProp}
    • 除此之外,这不仅仅是时间问题,而是安全问题。使用 Angular 的很大一部分好处是它承担了为您操作 DOM 的负担。否则,每次您在 Angular 中进行直接 DOM 操作时,您都需要追溯任何有助于您的 DOM 操作的变量,以确保它们永远不会来自任何类型的用户输入(并且未来的任何更改都不会出现这种情况——一个艰巨的任务)。为什么?安全性,在某种程度上类似于 SQL 注入(概念上)。主要是服务端渲染的 b/c。
    • 小心TrackByFunction&lt;T&gt; 的签名 - 顺序实际上是相反的,例如*ngFor="let row of rows; trackBy: myTrackBy",在模板中,它是 myTrackBy(index: number, item: T) 与元素具有的任何类型 T
    【解决方案2】:

    下面是正确的检查。

    div.addEventListener('click', (e) => {
      this.popUp(e);
    });
    

    【讨论】:

      【解决方案3】:

      问题是你正试图用纯 javascript 做 Angular 的东西。

      &lt;div (click)="method()"&gt; 是有角度的。 在 javascript 中你会做这样的事情&lt;button onclick="myFunction()"&gt;Click me&lt;/button&gt; 其他选项是使用事件处理程序https://www.w3schools.com/js/js_htmldom_eventlistener.asp

      无论如何,Angular 不建议更改 DOM,因为那样它就无法识别这些更改。以下是正确更改 dom 的多个示例

      【讨论】:

        【解决方案4】:

        您可以如下图所示设置点击事件,而不是使用setAttribute

        div.addEventListener('click', (e) => {
          this.popUp(e);
        });
        

        【讨论】:

          【解决方案5】:

          (click)不是html属性,是Angular event binding syntax

          此语法由等号左侧括号内的目标事件名称和右侧带引号的模板语句组成。

          你不能在 JavaScript 中使用它。使用

          div.onclick = popUp;
          

          【讨论】:

            【解决方案6】:
            export class AppComponent {
                createEl(){
                  console.time("timer");
                  for (let i = 0; i < 10; i++) {
                    let div = document.createElement("div");
                    div.textContent = `Hello, World! ${i}`;
            
                    div.addEventListener('click', (e) => {
                      this.popUp(e);
                    });
            
                    document.getElementById('divEl')?.appendChild(div);
                  };
                  console.timeEnd("timer");
            }
            

            【讨论】:

            • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-23
            • 1970-01-01
            • 2018-01-04
            • 2017-07-30
            • 1970-01-01
            相关资源
            最近更新 更多