简体   繁体   中英

Ember.js binding an Ember object property to a controller property?

I am trying to bind the temperature property of my controller to the temp property of my settings object. I am attempting this in an ember generated controller file app/controllers/home.js

var settings = Ember.Object.create({
    temp: 66
});

export default Ember.Controller.extend({
    temperatureBinding: "settings.temp"
});

While trying different possible solutions I discovered that this code snippet works when I create my settings object like so:

 App = Ember.Application.create(); App.settings = Ember.Object.create({ temp: 65 }) App.Controller = Ember.Controller.extend({ temperatureBinding: 'App.settings.temp', }) 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Ember Starter Kit</title> <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://builds.emberjs.com/tags/v1.13.5/ember-template-compiler.js"></script> <script src="http://builds.emberjs.com/tags/v1.13.5/ember.debug.js"></script> </head> <body> <script type="text/x-handlebars"> Temperature: {{temperature}} </script> </body> </html> 

Unfortunately when I attempt this in my home.js file it throws an error because App is not defined in that file. Is this way of doing data binding even possible with Ember? If so, what I am doing wrong?

Notice that bindings are deprecated and should not be used .

Now lets discuss your examples. The first example can't work, because there is no way to access that settings variable. This is simple a JavaScript limitation. Its just a variable in closure context of the file, and there is no way to access the current or an outer closure context dynamically.

So if you just have the String "foo" you can't access the variable foo .

The second example works because some really strange magic, and should not be used anymore!

Basically if a binding starts with a capital letter (like A ) ember tries to resolve it on the global window context. Since you declare app in the local scope (you don't have a var in front of it) ember can access window.App.settings.temp by just doing window["App.settings.temp"] . Still, don't use it!


What you should use are computed properties and services. If you have some global state, create a service for it! So instead of a Binding with a capital letter use a service!

When you just want a simple alias so you don't have to write this.get('foo.bar') and just want to write this.get('bar') you should do it by a computed property.

Instead of

barBinding: 'foo.bar',

do

bar: Ember.computed.alias('foo.bar'),

You can combine this with services to have something like the capital letter binding:

myService: Ember.inject.service(),
foo: Ember.computed.alias('myService.foo'),

If you do so you will have the foo property, which is an alias to the foo property on the service and so global.


However what you can always do is just put a variable into a ember object:

var settings = {foo: 12};
export default Ember.Controller.export({
  settings:settings,
  foo: Ember.computed.alias('settings.foo'),
});

This will work as expected, except for one thing: The settings object is not an ember object and so not observable. if you do settings.foo=42; the foo computed property will not update .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM