你好Dart和Angular Folks,
以下问题:

我的app_component.html中有以下模板部分,这是我的app_component.dart自定义组件的模板。

<!-- monitoring active breakpoints-->
<jb-responsive-breakpoints [breakpoints]="breakpoints"
                           [(activeBreakpoints)]="activeBreakpoints">
</jb-responsive-breakpoints>

<!-- using list of active breakpoints -->
<jb-menu [activeBreakpoints]="activeBreakpoints">
    <!--some menu items, irrelevant for this problem-->
</jb-menu>

<!-- testing list of active breakpoints-->
Active Breakpoints:
<ul>
    <li *ngFor="let breakpoint of activeBreakpoints;"> {{breakpoint}}</li>
</ul>


Jb-response-breakpoints和jb-menu也是自定义组件。下面的ul测试了jb-response-breakpoints的正确功能。

在此模板中使用的变量“breakpoints”和“activeBreakpoints”是在app_component.dart中使用以下代码定义的:
//Mapping from window min-width for this breakpoint to label
Map<int, String> breakpoints = {0:'small', 310:'medium', 450:'large', 600:'xlarge'};

List<String> activeBreakpoints = new List<String>();

应该发生什么:
  • jb-response-breakpoints注册给定宽度的侦听器
  • 如果窗口的当前宽度超过一个断点,则将更新“activeBreakpoints”列表。此列表包含所有当前 Activity 的断点,例如css允许所有匹配的媒体查询一次处于 Activity 状态
  • 这似乎可以按预期工作,因为模板中的ul会相应更新。

  • 问题:

    jb-menu应该获取activeBreakpoints列表,以找出何时更改外观。 jb-menu上的activeBreakpoints属性是一个setter,就像事件处理程序一样。

    jb-menu上的activeBreakpoints属性的定义如下:
    List<String> _activeBreakpoints;
    
    @Input()
    set activeBreakpoints(List<String> breakpoints) {
      _log.finest("ActiveBreakpoints list changed");
      _log.finest("Active Breakpoints: ${breakpoints.fold("", (prevVal, elem) => "$prevVal, $elem")}");
      _activeBreakpoints = breakpoints;
    }
    
    get activeBreakpoints {
    return _activeBreakpoints;
    }
    

    行为:
    -以空列表调用setter-因初始化而合乎逻辑
    -不会在进一步的断点更改时调用Setter(可以通过日志消息来证明这一点-调整窗口大小时不会显示“activeBreakpoints更改”日志消息)
    -令人困惑:在ngAfterViewInit函数的jb-menu组件中记录 Activity 断点时,会按预期显示所有当前断点:
    @override
    ngAfterViewInit() {
      _log.finest(
        '''
        currentBreakpoints: $activeBreakpoints
        '''
      );
    }
    

    这将产生:
    currentBreakpoints: [small, medium, large, xlarge]
    

    或更少的断点,取决于窗口大小。

    我可以想象,这是由于列表引用在两个组件中都是相同的。

    但是我的菜单组件依赖于被称为setter的事件处理程序。

    一些想法如何解决这个问题?

    PS:如果需要更多代码/解释,请询问! :)

    最佳答案

    (不确定我是否理解您的问题-请谨慎使用)

  • Angular2更改检测仅比较对象引用,而不比较对象或数组内容。
    您可以创建列表currentBreakpoints = currentBreakpoints.toList()的副本,使其成为另一个实例,以进行更改检测以识别更改。
  • 您可以传递流而不是数组,并使用该流发出新值,以通知接收者有关更新的信息。如果传递的数组是同一实例,则对该数组的绑定(bind)可能仍不会更新。
  • 您可以实现DoCheck并使用IterableDiffers在每个更改检测周期检查内容是否已更改。
  • 08-16 14:33