使超类字段可观察

Posted

技术标签:

【中文标题】使超类字段可观察【英文标题】:Making Superclass Fields Observable 【发布时间】:2014-07-22 19:51:46 【问题描述】:

我正在尝试在 Dart 中使用 Polymer 创建一个自定义的“径向选择器”元素。

我当前的目标是为 RadialSelector 类创建一个可观察的“子”字段,以便我可以对子类进行模板循环并过滤那些仅属于特定元素类型的子类。

目前尚不清楚如何在不创建另一个与命名空间不冲突的变量的情况下使“children”字段可观察。例如,我可以创建一个“childs”字段,使其可观察,然后将其设置为等于 this.children。但这似乎很尴尬和样板。

我的 RadialSelector 类(它扩展了 PolymerElement 类)是否有办法使其超类“子”字段可观察?目前,当我只写@observable children 时,Dart(可以理解)认为我只是在创建一个新的“children”变量。

谢谢,如果有什么我可以说得更清楚的,请告诉我! :)

这是飞镖代码:

      import 'package:polymer/polymer.dart';
      import 'dart:html';

      @CustomTag('radial-selector')
      class RadialSelector extends PolymerElement 
        @published String img;
        @observable children;
        RadialSelector.created() : super.created()  
          print("CONSTRUCTING RADIAL SELECTOR");
          print(children);
           

        filterByType(Type t, List<Element> elems) 
          print("FILTER BY TYPE CALLED");
          List<Element> newElems = new List<Element>();

          for (var e in elems) 
            if (e.runtimeType == t)
              newElems.add(e);
          
          return newElems;
          
       

这里是对应的html:

<link rel="import" href="packages/polymer_ui_elements/polymer_ui_icon_button/polymer_ui_icon_button.html">

<polymer-element name="radial-selector">   
  <template>
    <style>
    :host 
    display: block;
    margin: 100px
    

    </style>
         <script>console.log("HEY");</script>

    <div id="stem">

     <img src = "img" alt ="Radial stem"/>

     <template repeat = "child in children | filterByType(ImageElement)">   
         <polymer-ui-icon-button src = child.src></polymer-ui-icon-button> 
     </template>
    </div>
  </template>
  <script type="application/dart" src="radialselector.dart"></script>
</polymer-element>

【问题讨论】:

【参考方案1】:

对于children,您无法做到这一点。

你可以创建一个@observable getter/setter 来重定向到超类的孩子

@observable
NodeList get children => super.children;
set children(NodeList val) => super.children = val; // won't work

这有两个缺陷。

children 列表为 final(尚未尝试,但我确定您无法分配新列表。 @observable children 对您毫无帮助。 只有在分配另一个列表时才会通知您(这是不可能的,因为该字段是最终的) 您需要一个可观察的列表来获得有关列表元素更改(添加/删除/替换)的通知。 为此,您需要将 children 替换为 toObservable(children),这是不可能的,因为您无法替换 children 集合。

您可以使用MutationObserver。请参阅Angular Dart - execute a function right after ng-repeat has finished 以获取有关子节点更改的通知。

您可以添加一个新字段

@observable List myChildren;

并在孩子发生变化时使用突变观察者更新此字段。

void mutationCallback(...) 
  ...
  myChildren = children.toList();

这样每次您的孩子更改 myChildren 时,都会分配一个全新的列表,并且由于 @observable 注释,视图会收到有关此更改的通知。 您不需要使列表可观察,因为没有要观察的单个添加/删除/替换操作。

【讨论】:

以上是关于使超类字段可观察的主要内容,如果未能解决你的问题,请参考以下文章

在 knockout.js 中进行 ajax 检索后使字段可观察

敲除可观察字段未在输入值更改时更新

RxJs:根据字段值更改创建可观察对象

Knockoutjs 单击并编辑字段不更新可观察的

使用 Linq 一次更新可观察集合项的两个字段

重构摘要11_处理概括关系