Ember:为什么当观察者触发时计算不触发?

Bri*_*yko 1 ember.js

我很难理解这一点 - 我正在使用继承的遗留代码,虽然这看起来应该非常简单,但事实并非如此。

在此 app/pods/application/route.js 中,有一个由服务器抓取的“welcome pack”对象,作为该对象的一部分,在welcome-pack 服务上调用了一个 setWp() 方法,该方法设置“wp”相同服务的价值。(是的,我知道您可能可以使用“this.wp.set('wp',welcomePack)”直接在服务上设置值,但正如我所说:继承了遗留代码。)重点是,这应该会触发价值。我的 wp.wp 观察者正在触发,但不是我基于 wp.wp 的计算结果。有什么线索吗?

// app/pods/application/route.js
wp: inject('welcome-pack'),
model(){
  return this.store.findAll('welcome-pack').then((welcomePack) => {
  this.wp.setWp(welcomePack);
})
}



// app/pods/welcome-pack/service.js
import Service from '@ember/service';
export default Service.extend({
  wp: null,
  setWp(wp){ // <-- called when the model loads from the ajax request
    this.set('wp', wp)
  }
})

// app/pods/application/controller.js
import Controller from "@ember/controller";
import { inject } from "@ember/service";
import { computed, observer } from "@ember/object";

export default Controller.extend({
  wp: inject("welcome-pack"),
  init(){
    console.log('this.wp', this.wp) // <- logs service as class
    console.log('this.wp.wp', this.wp.wp) // <-logs null
    setTimeout(() => {
      // set for after the ajax call has been made and setWp() has been called. 
      console.log('this.wp', this.wp) //<- logs service as class
      console.log('this.wp.wp', this.wp.wp) //<- logs object as class
    }, 2000)
  },
  obsWPChanges: observer('wp', function(){
    console.log('wp changed'); // <-- never executes (don't expect it to)
  }),
  obsWPWPChanges: observer('wp.wp', function(){
    console.log('wp.wp changed') //<-- executes (as expected) when setWP() is called
  }),
  primaryColor: computed("wp.wp", function() {
    console.log("this.wp.primaryColor", this.wp.primaryColor) // <-- does not execute
    return this.wp.wp.primaryColor || "#37b3c0";
  }),
  secondaryColor: computed("wp.wp", function() {
    return this.wp.wp.secondaryColor || "#38a0d0"; // <-- does not execute
  })
});
Run Code Online (Sandbox Code Playgroud)

mis*_*nry 5

在 Ember 中,计算属性是延迟求值的。因此,在它们被引用之前,它们永远不会被执行。

另一方面,观察者在依赖键发生变化时总是会触发。您上面显示的行为是完全可以解释的,假设primaryColor此时secondaryColor从未被引用。摘自文档

计算属性仅在使用时才会重新计算其值。属性以两种方式消耗:

例如,通过访问ironMan.fullName

例如,通过在当前正在呈现的把手模板中引用, {{ironMan.fullName}}在这两种情况之外,即使属性的依赖项之一发生更改,属性中的代码也不会运行。

我记得你在 Ember subreddit 上的长篇大论,希望你玩得开心。既然您已经积累了一些经验,我强烈建议您仔细阅读这些文档。

  • 另外,如果您已经了解 ES6,那么直接开发到开发,Ember 并不难。阅读该指南最多需要一个小时,如果您仔细阅读并做一些实际示例,则需要两个小时。 (2认同)