Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/462.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 奥雷利亚';它是用一个对象计算出来的_Javascript_Typescript_Aurelia - Fatal编程技术网

Javascript 奥雷利亚';它是用一个对象计算出来的

Javascript 奥雷利亚';它是用一个对象计算出来的,javascript,typescript,aurelia,Javascript,Typescript,Aurelia,我有一个状态对象,它有一个属性会话,这个属性可以是对象或空 我不想对isSessionActive()getter进行脏检查,所以我想使用computedFrom()。但是,当此对象更改时,computerFrom()似乎不会激发,除非它以前未定义 在我的状态存储上没有专用的isSessionActiveboolean属性,我可以这样做吗 @autoinject export class Home { firstName: string = "user"; private sta

我有一个
状态
对象,它有一个属性
会话
,这个属性可以是
对象

我不想对
isSessionActive()
getter进行脏检查,所以我想使用
computedFrom()
。但是,当此对象更改时,
computerFrom()
似乎不会激发,除非它以前未定义

在我的状态存储上没有专用的
isSessionActive
boolean属性,我可以这样做吗

@autoinject
export class Home {
    firstName: string = "user";
    private state: State;

    constructor(private store: Store) {
       store.state.subscribe(
            response => this.state = response
       )
    }

    @computedFrom('state.activeSession')
    get isSessionActive() {
        return this.state.activeSession !== null;
    }
}

我最后只是做了以下几件事:

isSessionActive: boolean = false;

constructor(private store: Store) {
    store.state.subscribe(
        response => { 
            this.state = response;
            this.isSessionActive = response.activeSession !== null;
        }
    )
}

我可以看出你已经解决了你的问题,但这是一个变通办法,而不是实际的解决办法。因此,我想提出一些解释,解释一下你为什么会遇到这种情况,以及如何解决它。基本上,你的问题与所描述的同一个问题是完全不同的

我在评论部分提供了一个详细的解释,因为有一个猜测答案,所以我将在这里重复我自己


重要的代码位如下:

private state: State;

// ...

@computedFrom('state.activeSession')
正如我已经解释过的,Aurelia变更检测的工作方式是,当Aurelia参与观察某个值时,它会设置自定义的getter和setter来代替相应的字段或属性。基本上,setter所做的是调用原始属性setter(或设置原始支持字段),然后通知任何相关方(即绑定到该属性的任何方)值已更改

如果这对你来说没有意义,那也没关系。重要的是,每当你绑定到某个东西时,在绑定设置之前,某个东西必须就位。如在的评论部分所述,如果您写下以下内容:

private state: State;
这只是对TypeScript的一个提示,
state
在定义类上语义正确。换句话说,由于您没有将其设置为任何值,它被完全排除在传输的JavaScript代码之外——它所做的只是使
状态的使用在TypeScript中有效

例如,如果您这样做:

class A {
  x: number;
}
然后生成的JavaScript将类似于:

function A() {
}
请注意,没有
此.x
!但是,如果您写了以下内容:

class B {
  x: number = undefined; // or null, or whatever you like
}
然后生成的JavaScript将是:

function B() {
  this.x = undefined;
}
两者之间的区别在于,在第一种情况下,没有可绑定的属性。因此,Aurelia无法订阅它,因为它无法知道该属性何时(在JavaScript中)开始存在于对象上。这里需要注意的是,如果您在控制台中这样检查值:

var a = new A();
var b = new B();
console.log(a.x); // undefined
console.log(b.x); // undefined
a.x
b.x
似乎都是
未定义的
。但是它们是不同的:
a.x
未定义的
,因为它在
a
上不存在,而
b.x
未定义的
,因为它被显式地分配了一个值
未定义的
,所以它确实存在,只是碰巧有一个值
未定义的
。后一种场景确实允许Aurelia在属性上设置其自定义逻辑,而前一种场景则不允许


总之,要使计算的属性正常工作,只需为其计算中涉及的所有属性指定一个默认值(例如
undefined
null
)。无论如何,这是一个很好的做法。

也许这会有所帮助,因为我已经订阅了我商店的状态。我可以简单地触发回调事件并手动更新getter,但它没有那么干净。我认为应该设置
state.activeSession
,而不是将对象替换为
this.state=response
。您所拥有的应该可以工作,但它只会在
state.activeSession
更改时调用getter,如果
state.activeSession.foo
发生更改,则不会更改。它只会注意到整个对象何时被调出,而不会注意到对象上的属性何时发生更改。对,这就是我在@AshleyGrant看到的,以及我在其他地方用
@observable
@computedFrom
观察到的。这是令人失望的。看到我上面的答案,我可能会像你在这个答案中那样完成这项工作,因为它的代码更少,但是你可以在getter上使用
@computedFrom('state
)`来完成。谢谢,这很有意义。这是较少的代码,但我觉得不太干净。我想这只是我的感觉。谢谢,这提供了很多背景。