Aurelia prints __observers__ instead of object

拈花ヽ惹草 提交于 2019-12-24 10:31:09

问题


I am trying to bind an object from the view-model to view as follows:

// welcome.js
export class Welcome {

constructor() {
    this.data = {
        a: "",
        b: "",
        c: ""
    }
}

submit() {
       console.log(this.data);
    }
}


// welcome.html
<form role="form" submit.delegate="submit()">
    <div class="form-group">
      <textarea class="form-control" value.bind="data.a" rows="3"></textarea>
    </div>
    <button type="submit" class="btn btn-default">Submit</button>
</form>

Ideally, it should print only data object. However, it prints following output in the console.

I would like to know what is observers object and how can I access only data object. Thank you.


回答1:


Short answer:

The __observers__ object is what makes change detection possible for Aurelia, you cannot get rid of that. If you really need to extract precisely what you want then you need to do that by hand.

A bit more in-depth

Normally, when you define some data on the viewmodel, developers typically don't mind setting up properties explicitly, they use the field notation instead, since this is more concise. However, fields are just fields, what happens on read or assignment cannot be altered1.

Whenever a property that is bound to by any means - such as using it in template interpolation (${ data.a }) or binding (<input value.bind="data.a" />), etc. - changes, then Aurelia needs a way of being notified if and when the value changes so it can update anything that relies on it, such as parts of your view.

Because of 1, if something is defined as a field, it is not possible. So what Aurelia does is that it transforms fields on your classes on the fly into properties since they still allow the x = 1 notation (what you use when dealing with fields) unlike the Java-style get-set methods (setX(1)) letting your code work exactly as intended but they also enable executing arbitrary logic both in the getter as well as the setter. As it transforms the fields into properties, it also injects some logic of its own which notifies Aurelia whenever the value changes.

That's why those things are added to your object and that's why you cannot get rid of them. They are absolutely necessary to enable the framework to do its job.


On a side note, of course, there are other ways to enable change detection, but each of them comes with its own quirks. For example, in Angular, this is not necessary, because what Angular does is it executes change checks whenever some asynchronous event occurs:

Angular executes template expressions after every change detection cycle. Change detection cycles are triggered by many asynchronous activities such as promise resolutions, http results, timer events, keypresses and mouse moves.

Of course, this comes with different complications, such as you need to write code like this every now and then just to set some value:

setTimeout(() => this.someVal = 0, 0);

which is really hacky in my opinion.


So basically there are two ways for a framework to get notified when something changes. One is the Aurelia way and the other is the Angular way.

The Aurelia way comes with the consequences that you are asking about, that is, it adds some other stuff to your objects.

Angular, on the other hand, necessitates such hacky solutions as above and one might also wonder about the performance implications of doing change checks in response of most async events.




回答2:


To get your plain object you can use a cloning technique: console.log(JSON.parse(JSON.stringify(this.data)))



来源:https://stackoverflow.com/questions/48777507/aurelia-prints-observers-instead-of-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!