我想在这个问题的开头说我已经阅读并理解了其他可能重复的问题(例如 this one )并且无法完成这项工作,这导致我相信这个问题的性质有点不同,或者我误解了一些东西。

上下文: 我有一个带有两个子组件(一个侧菜单和一个主 View )的父组件。侧边菜单有一些过滤器,它们是通过 [(ngModel)] 绑定(bind)到对象的复选框形式,并在模板中使用 (ngModelChange)="changeFilter()" 触发事件。

在父组件中,我捕获了事件: (filter)="updateFilters($event)" 。此函数更改一个公共(public)过滤器变量,然后我将其传递给另一个子组件,如下所示:[filterObject]="filters"
在主 View 组件中,我将 filterObject 变量提供给管道以过滤对象数组。

问题: 在我第一次更改过滤器后,管道仅被调用一次。主 View 中的 filterObject 变量在像这样 {{filterObject | json}} 显示时显示正确更新,但从未调用 setter。放入 setter 和 getter 的控制台日志显示只有 getter 可以访问 (2-4)

我尝试过的解决方案:

  • 向管道添加附加参数以触发它。这种方法的问题在于,需要从 filterObject 的 setter 中设置新日期,而 Object.assign 不会被调用 - 如上所述
  • 使管道不纯(有效但不是一个很好的解决方案,因为它每次单击处理非常大的复杂对象数组 2-4 次)
  • 让父级更新过滤器变量,不是通过赋值运算符,而是通过 ojit_code 以更改引用并可能触发 setter

  • 我正在考虑的解决方案: 如果我无法弄清楚问题出在哪里,我正在考虑通过观察者在两个组件之间进行通信。否则,我可能不得不适应嵌入了一些自定义更改检测的不纯管道(我正在考虑将过滤器对象转换为 JSON 字符串并检查长度)。

    side-menu-component.html
    <input type="checkbox" id="filter-type-2" name="filter-type-2" [(ngModel)]="filterObject.type.me" (ngModelChange)="changeFilter()">
    

    side-menu-component.ts
     @Output() filter = new EventEmitter();
     public filterObject = {
        type: {
            mo: true,
            me: true,
            ar: true,
            cto: true,
            gl: true,
            dl: true
        },
        status: {
            unreviewed: true,
            approved: true,
            other: true
        }
    };
    
    // ...
    
    changeFilter() {
        this.filter.emit(this.filterObject);
    }
    

    父组件.html
    <aside>
         <app-article-view-aside [article]="article" (close)="closeModal($event)" (filter)="updateFilters($event)"></app-article-view-aside>
    </aside>
    <div class="articleContainerMainView">
         <app-article-view-main [article]="article" [filterObject]="filters"></app-article-view-main>
    </div>
    

    父组件.ts
    updateFilters(newFilter) {
        this.filters = newFilter;
    }
    

    主 View 组件.html
    <app-finding
            *ngFor="let finding of findings | findingsFilter:filterDate:filterObject; let i = index"
            [finding]="finding"></app-finding>
    

    主 View 组件.ts
    @Input() set filterObject(filterObject) {
        console.log('setter');
        this._filterObject = filterObject;
        this.filterDate = Date.now();
    }
    
    get filterObject() {
        console.log('getter');
        return this._filterObject;
    }
    
    private _filterObject = {};
    
    public filterDate = Date.now();
    

    首次显示页面时的控制台输出:
    setter
    getter
    getter
    getter
    getter
    

    我真的很想用“Angular 方式”来做,所以我对你的问题是我在这里错过了什么?

    最佳答案

    可能是您的侧边菜单组件发出相同的对象。它的内容可能会改变,但发出的对象仍然相同。考虑发出对象的副本。 Object.assign({}, this.filterObject) 可以帮到你。

    关于 Angular 输入 setter 仅触发一次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51264978/

    10-09 23:13