【问题标题】:Why Angular doesn't detect changes when used to develop chrome extension popup?为什么 Angular 在用于开发 chrome 扩展弹出窗口时不会检测到更改?
【发布时间】:2021-04-23 12:13:51
【问题描述】:

我正在开发一个简单的书签 chrome 扩展并使用 Angular 作为框架,可能不是此类任务的最佳选择,但我想尝试一下。

在这篇文章之后here 这一切似乎都是合乎逻辑的。但是,我开始遇到非常奇怪的问题。

当我单击书签图标时,书签视图输入未填充来自 chrome API 的值(似乎 Angular 不会启动更改检测或类似的东西,我是前端和 Angular 的新手一般的)。为了更改视图,我需要单击其中一个输入,然后在视图更改后单击另一个输入。

另一个观察结果是,当我使用<select> 输入时,当我选择一个输入不会更改的选项时,我需要单击其中一个文本输入才能看到更改。我相信必须填写输入,因为代码chrome.tabs.query 在组件的构造函数中执行。我怀疑这段代码在 Angular 之外运行,因此 Angular 不会触发更改检测,所以我尝试了ChangeDetectorRef.detectChanges(),当我单击书签图标时它可以更新输入,但这并没有解决问题<select>,所以问题可能更深入。

这是组件代码:

import {Component, OnInit} from '@angular/core';

@Component({
    selector: 'app-add-bookmark',
    templateUrl: './add-bookmark.component.html',
    styleUrls: ['./add-bookmark.component.css']
})
export class AddBookmarkComponent implements OnInit {


    url: string = "";
    directory: string = "";
    description: string = "";
    tags: string[] = [];
    image: string;
    recentFolders = [];
    folderId: string = "2";

    constructor() {
        chrome.tabs.query({active: true, currentWindow: true}, tabs => {
            let activeTab = tabs[0];
            this.url = activeTab.url;
            this.description = activeTab.title;
            this.image = activeTab.favIconUrl;
           // ChangeDetectorRef.detectChanges(); //this worked and inputs are updated but It didn't solve the issue with Select. 
        });

    }
}  

HTML:

<div class="container align-items-center p-2">
    <div class="row align-items-center">
        <div class="col-sm-1">
            <div class="mb-1">
                <img *ngIf="image" [src]="image"/>
            </div>
            <div class="mb-1">
                <label for="url" class="form-label">URL</label>
                <input type="text"
                       class="form-control form-control-sm" id="url"
                       aria-describedby="url" [(ngModel)]="url" name="url">

            </div>
            <div class="m-1">
                <label for="description" class="form-label">Description</label>
                <textarea type="text" class="form-control form-control-sm" id="description" aria-describedby="desc"
                          [(ngModel)]="description" name="description"></textarea>
            </div>
            <div class="m-1">
                <label for="description" class="form-label">Select Folder:</label>
                <select id="selected_dirs" class="form-select form-control form-control-sm"
                        aria-label="Default select example"
                        name="directory">
                    <option *ngFor="let f1 of recentFolders" [ngValue]="f1.id">{{f1.name}}</option>

                </select>
            </div>
            <div class="mt-4 mb-2">

                <button class="btn btn-primary btn-sm" (click)="openManager()">Open Manager</button>
                <button class="btn btn-dark btn-sm m-2" (click)="addBookmark()">Add bookmark</button>
            </div>

        </div>
    </div>
</div>

这是一个视觉演示

应该填写URL和描述

单击输入字段,没有任何反应

点击另一个输入框就可以了

这是书签中的“检查”窗口。

感谢您花时间阅读这个长长的问题。

【问题讨论】:

  • 以防万一您不知道,弹出窗口是一个单独的窗口,因此它有自己独立的开发工具:在弹出窗口内右键单击并在菜单中选择“检查”。在 devtools 中,您可以检查控制台中的错误并调试您的代码。

标签: javascript angular google-chrome google-chrome-extension


【解决方案1】:

我认为,问题在于角度检测。每当组件中的数据发生任何变化时,它都会像这样运行变化检测以在视图上呈现此变化。可以有两种策略 OnPush 或 default。您可以像这样启用它:

@Component({
    selector: 'app-add-bookmark',
    templateUrl: './add-bookmark.component.html',
    styleUrls: ['./add-bookmark.component.css'],
    changeDetection: ChangeDetectionStrategy.OnPush. //you can change it to default ChangeDetectionStrategy.Default
})

在这种情况下(默认),只要组件中的数据发生变化,Angular 就会自行运行。但这会让事情变得有点滞后,你检查一下它是否适合你。

所以,我的建议是,每当您对视图进行任何更改时,都需要运行更改检测来更新视图。为此,请添加一个 Hostlistener,并且每当用户单击此组件时,您都可以触发更改检测。

import { HostListener } from '@angular/core'; // add in component file
 @HostListener('click', ['$event'])
onMouseEnter(event: any) {    
      
  //Run change detection.
  this.changeDetection();
}

public changeDetection() { 
   this.ChangeDetectorRef.detectChanges();
}

此侦听器将仅限于此组件。如果您想了解有关更改检测的更多详细信息:https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

另外,如果您在调试时遇到任何上下文问题,您可以使用 Ngzone:https://angular.io/guide/zone

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2016-11-28
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多