aurelia属性观察从父

时间:2015-12-21 20:56:27

标签: aurelia aurelia-binding

我对aurelia有疑问。假设我有一个产品类,这个产品有标签。一个具体的例子:衬衫是一种产品,它有一些用户可以查询的标签,如Men,XL,blue等。他们的JSON表示就像

{
  "id": 3,
  "name": "Shirt",
  "sku": "WCZR-1",
  "tags": [
    {
      "id": 1,
      "name": "XL"
    },
    {
      "id": 2,
      "name": "Blue"
    }
  ]
}

如果管理员正在查看此产品的详细视图并且可以编辑标签,则他将按如下方式查看视图:

<div class="form-group">
                <label>SKU</label>
                <input type="text" value.bind="item.sku">
</div>
<div class="form-group">
    <label>Tags</label>
        <tag-manager item.bind="item"></tag-manager>
</div>

请注意,我有另一个名为<tag-manager>的自定义元素,它是product detail元素的子元素。您可能已经猜到,它在其导出中公开了一个可绑定对象:@bindable item = null;

这样,父元素将产品传递给子元素,管理员可以使用此标记管理器添加\ remove标记。为了让管理员能够编辑标签,他需要点击编辑按钮。 这会将项目置于编辑模式。父元素(产品详细信息元素)通过在用户单击编辑按钮时向产品添加InEditMode属性来实现。

enterEditMode(){
    this.item.inEditMode = true;
    this.savedItem = JSON.parse(JSON.stringify( this.item ));
}

请注意,inEditMode属性不是来自web api,而是动态添加的。

现在,这主要有效,当产品处于编辑模式时,子元素(标记管理器)可以从产品中添加\ remove标记,父和子都可以看到修改了产品标记集合。标签管理器的示例代码:

removeTag(tag){
    this.item.tags = this.item.tags.filter(function(el){
        return el.id !==tag.id;
    })
}

addTag(tag){
    this.item.tags.push(tag);
}

这些函数成功地处理和修改了项目的标记集合,有一件事是 product.InEditMode 属性。当父元素(详细视图将产品置于编辑模式时,标记管理器仅识别视图激活。但是在初始加载后单击父级的编辑|取消并更改父级中的inEditMode属性)因此,虽然正在观察产品的tag属性,但是孩子没有观察到inEditMode属性。如果我在aurelia中导入观察者定位器并观察属性,它就没有区别。代码:

import {ObserverLocator} from 'aurelia-framework';

    var subscription = this.observerLocator
      .getObserver(this.product, 'inEditMode')
      .subscribe(this.onChange);
  }
      onChange(newValue, oldValue) {
      //this method is called only once at the activation of the child,
      //no clicks in the parent can trigger this method again
      }

如评论中所示,onChange方法仅在激活时被调用一次;激活后,父元素的任何点击(编辑,取消编辑)都不会反映在子元素中,并且不会再次调用onChange。

我能够通过使用eventAggregator来实现这一点,但我真的想知道为什么我无法从父级观察对象的bool属性。我不想滥用eventAggregator不了解幕后发生的事情。任何线索将不胜感激!

修改

此问题的吸收者在

http://plnkr.co/edit/0gMZFhtKA2r6nec9kGUC?p=preview

与我看到的问题略有不同,但子视图仍未反映父视图模型的更改。

1 个答案:

答案 0 :(得分:0)

我建议使用BindingEngine

略有不同的方法
@bindable product;
productChanged(newValue, oldValue) {
  if (this.inEditModeSubscription) {
    this.inEditModeSubscription.dispose();
    this.inEditModeSubscription = null;
  }
  if (newValue) {
      this.inEditModeSubscription = this.bindingEngine
          .propertyObserver(newValue, "inEditMode")
          .subscribe(this.onEditModeChanged);
  }
}
inEditModeSubscription = null;

product.inEditMode中添加productChanged的属性 - 观察者,确保您不会意外地将观察者添加到nullundefined对象,并且会刷新只要您将product设置为其他对象,就会进行订阅。

这可确保在属性更改时始终触发onEditModeChanged