具有多个依赖项的Ember属性不会按预期更新

Ember properties with multiple dependencies dont update as expected

本文关键字:更新 属性 Ember 依赖      更新时间:2024-05-22

关于理解成员属性,我有以下问题:

如果我有房产a:

propertyA: function() {
  return this.get("propertyB.someObject.someValue");
}.property("propertyB")

和一个属性B:

propertyB: function() {
  return this.get("propertyX.someObject");
}.property("propertyX", "propertyY", "propertyZ")

我在一些模板中有一个属性a的绑定,比如:

{{propertyA}}

然后,在我的代码中90%的情况下,当i设置时,属性A没有得到正确更新,即propertyX

如果我理解正确,那么一旦其中一个依赖属性(如propertyX)发生更改,propertyB就会变为dirty。这将自动使propertyA变脏,并因此自动更新它,因为它具有绑定。

在我的代码中发生的情况是,即使我在控制台中调用propertyA,它仍然是旧的缓存值,但当我调用propertyB时,它会重新评估并返回更新的代码,因为它是脏的。

问题是,为什么propertyA不会自动变脏,而propertyB会变脏?是因为属性B在模板中没有绑定吗?我认为如果属性A具有依赖性,就没有必要这样做。

我还发现,当propertyB只依赖于propertyX时,这个问题就不会发生,所以多依赖性一定会以某种方式把事情搞砸。

很抱歉有这么复杂的解释,但我试图尽可能简单地抽象我的实际代码。

更新:

好的,这里有一些实际的代码:

控制器:

styling: function() {
  var clipValues = this.get("clip.styling") || {};
  var infoValues = this.get("clip.info.styling") || {};
  return Ember.Object.create(jQuery.extend({}, clipValues, infos));
}.property("clip.styling", "clip.info.styling"),

showBottombar: function() {
  return (!!this.get("bottombarSrc") || !!this.get("styling.bottombar.fancyStuff"));
}.property("styling"),

在其他地方,剪辑被设置为这个控制器。稍后,它的信息会在剪辑模型中更新,这是一个简单的Ember。对象:

getInfo: function(url) {
  var self = this;
  return App.ajax(url).then(function(response) {
    self.set("info", response);
  });
}

现在,在调用getInfo之后,模板中的{{showBottombar}}显示"false",即使"bottombarSrc"answers"…fancyStuff"为true。当我从控制台调用"样式"时,它会重新评估样式代码,该代码指示在clip.getInfo发生后它被标记为脏的(它设置了"信息")。但这并没有影响Bottombar的演出。只是之后没有人叫它。

更新2

有两种奇怪的方法可以让它发挥作用,但我不明白为什么:

第一个是向模板添加样式绑定:

{{styling}}

这导致showBottombar在造型改变后被调用。

第二个是从样式属性中删除其他依赖项:

styling: function() {
  var clipValues = this.get("clip.styling") || {};
  var infoValues = this.get("clip.info.styling") || {};
  return Ember.Object.create(jQuery.extend({}, clipValues, infos));
}.property("clip.info.styling"),

(不再依赖"clip.styleing")。这也导致showBottombar属性正常工作。两种方式都可以单独使用。

 propertyA: function() {
   return this.get("propertyB.someObject.someValue");
 }.property("propertyB").volatile()

http://emberjs.com/api/classes/Ember.ComputedProperty.html#method_volatile