Ember.js:如何从视图调用模型中定义的方法?

Ember.js:如何从视图调用模型中定义的方法?,ember.js,ember-data,Ember.js,Ember Data,我正在为《世界时间》开发一款应用程序。我有一个余烬模型:时钟 我想每秒更新时钟的time属性 现在,我已经在clock中定义了一个start方法,该方法负责更新clock模型的time属性 关于这一点,我有两个问题: 1.如何从视图中调用模型的start方法 2.有没有更好的办法 这是我的模型、视图、控制器、路由器和模板(如果您感兴趣): 型号: App.Clock = DS.Model.extend({ city: DS.attr('string'), country: DS.

我正在为《世界时间》开发一款应用程序。我有一个余烬模型:
时钟

我想每秒更新时钟的
time
属性

现在,我已经在clock中定义了一个
start
方法,该方法负责更新clock模型的time属性

关于这一点,我有两个问题: 1.如何从视图中调用模型的
start
方法 2.有没有更好的办法

这是我的模型、视图、控制器、路由器和模板(如果您感兴趣):

型号:

App.Clock = DS.Model.extend({
    city: DS.attr('string'),
    country: DS.attr('string'),
    latitude: DS.attr('string'),
    longitude: DS.attr('string'),
    time: DS.attr('date'),
    order: DS.attr('number'),

    start: function() {
        var clock = this;

        var updateTime = function() {
            var timezoneService = Utilities.TimezoneService;

            timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
                clock.set('time', timezoneService.getDateTime(timezone.offset));
            });
        };

        updateTime();

        window.setInterval(function() {
            updateTime();
        }, 1000);
    }
});
App.ClocksView = Ember.View.extend({
  templateName : 'world_clock/clocks'
});

App.ClocksNewView = Ember.View.extend({
  templateName : 'world_clock/new'
});
App.ClocksController = Ember.ArrayController.extend({
    sortProperties: ['order']
});

App.ClocksNewController = Ember.ObjectController.extend({
    city: null,
    save: function() {
        var cityName = this.get('city');
        if(!cityName.trim()){
            return;
        }

        var locationService = Utilities.LocationService.getInstance();

        locationService.lookupLocation(cityName, function(location) {
            var city = location.city;
            var country = location.country;
            var lat = location.latitude;
            var lon = location.longitude;

            if(city && country && lat && lon) {
                var clks = App.Clock.find({ city: city });
                clks.on('didLoad', function() {
                    if(clks.get('length') === 0) {
                        var clock = App.Clock.createRecord({
                            city: location.city,
                            country: location.country,
                            latitude: location.latitude,
                            longitude: location.longitude,
                            order: 10
                        });

                        clock.save();
                    }
                });
            }
        });

        this.set('city', '');

        this.get('target').transitionTo('clocks');
    }
});
App.Router.map(function() {
    this.resource('clocks', { path: '/' }, function() {
        this.route('new');
    });
});

App.ClocksRoute = Ember.Route.extend({
    model: function() {
        var locationService = Utilities.LocationService.getInstance();

        locationService.getLocation(function(location) {
            App.Clock.createRecord({
                city: location.city,
                country: location.country,
                latitude: location.latitude,
                longitude: location.longitude,
                order: -10
            });
        });

        return App.Clock.find();
    }
});
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
    {{#each controller}}
    <li>{{city}}, {{country}} - {{time}}</li>
    {{else}}
    You have not defined any clock yet.
    {{/each}}
</ul>
<form {{action "save" on="submit"}}>
    {{view Ember.TextField valueBinding="city" placeholder="City"}}
    <button>Save</button>
</form>
视图:

App.Clock = DS.Model.extend({
    city: DS.attr('string'),
    country: DS.attr('string'),
    latitude: DS.attr('string'),
    longitude: DS.attr('string'),
    time: DS.attr('date'),
    order: DS.attr('number'),

    start: function() {
        var clock = this;

        var updateTime = function() {
            var timezoneService = Utilities.TimezoneService;

            timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
                clock.set('time', timezoneService.getDateTime(timezone.offset));
            });
        };

        updateTime();

        window.setInterval(function() {
            updateTime();
        }, 1000);
    }
});
App.ClocksView = Ember.View.extend({
  templateName : 'world_clock/clocks'
});

App.ClocksNewView = Ember.View.extend({
  templateName : 'world_clock/new'
});
App.ClocksController = Ember.ArrayController.extend({
    sortProperties: ['order']
});

App.ClocksNewController = Ember.ObjectController.extend({
    city: null,
    save: function() {
        var cityName = this.get('city');
        if(!cityName.trim()){
            return;
        }

        var locationService = Utilities.LocationService.getInstance();

        locationService.lookupLocation(cityName, function(location) {
            var city = location.city;
            var country = location.country;
            var lat = location.latitude;
            var lon = location.longitude;

            if(city && country && lat && lon) {
                var clks = App.Clock.find({ city: city });
                clks.on('didLoad', function() {
                    if(clks.get('length') === 0) {
                        var clock = App.Clock.createRecord({
                            city: location.city,
                            country: location.country,
                            latitude: location.latitude,
                            longitude: location.longitude,
                            order: 10
                        });

                        clock.save();
                    }
                });
            }
        });

        this.set('city', '');

        this.get('target').transitionTo('clocks');
    }
});
App.Router.map(function() {
    this.resource('clocks', { path: '/' }, function() {
        this.route('new');
    });
});

App.ClocksRoute = Ember.Route.extend({
    model: function() {
        var locationService = Utilities.LocationService.getInstance();

        locationService.getLocation(function(location) {
            App.Clock.createRecord({
                city: location.city,
                country: location.country,
                latitude: location.latitude,
                longitude: location.longitude,
                order: -10
            });
        });

        return App.Clock.find();
    }
});
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
    {{#each controller}}
    <li>{{city}}, {{country}} - {{time}}</li>
    {{else}}
    You have not defined any clock yet.
    {{/each}}
</ul>
<form {{action "save" on="submit"}}>
    {{view Ember.TextField valueBinding="city" placeholder="City"}}
    <button>Save</button>
</form>
控制器:

App.Clock = DS.Model.extend({
    city: DS.attr('string'),
    country: DS.attr('string'),
    latitude: DS.attr('string'),
    longitude: DS.attr('string'),
    time: DS.attr('date'),
    order: DS.attr('number'),

    start: function() {
        var clock = this;

        var updateTime = function() {
            var timezoneService = Utilities.TimezoneService;

            timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
                clock.set('time', timezoneService.getDateTime(timezone.offset));
            });
        };

        updateTime();

        window.setInterval(function() {
            updateTime();
        }, 1000);
    }
});
App.ClocksView = Ember.View.extend({
  templateName : 'world_clock/clocks'
});

App.ClocksNewView = Ember.View.extend({
  templateName : 'world_clock/new'
});
App.ClocksController = Ember.ArrayController.extend({
    sortProperties: ['order']
});

App.ClocksNewController = Ember.ObjectController.extend({
    city: null,
    save: function() {
        var cityName = this.get('city');
        if(!cityName.trim()){
            return;
        }

        var locationService = Utilities.LocationService.getInstance();

        locationService.lookupLocation(cityName, function(location) {
            var city = location.city;
            var country = location.country;
            var lat = location.latitude;
            var lon = location.longitude;

            if(city && country && lat && lon) {
                var clks = App.Clock.find({ city: city });
                clks.on('didLoad', function() {
                    if(clks.get('length') === 0) {
                        var clock = App.Clock.createRecord({
                            city: location.city,
                            country: location.country,
                            latitude: location.latitude,
                            longitude: location.longitude,
                            order: 10
                        });

                        clock.save();
                    }
                });
            }
        });

        this.set('city', '');

        this.get('target').transitionTo('clocks');
    }
});
App.Router.map(function() {
    this.resource('clocks', { path: '/' }, function() {
        this.route('new');
    });
});

App.ClocksRoute = Ember.Route.extend({
    model: function() {
        var locationService = Utilities.LocationService.getInstance();

        locationService.getLocation(function(location) {
            App.Clock.createRecord({
                city: location.city,
                country: location.country,
                latitude: location.latitude,
                longitude: location.longitude,
                order: -10
            });
        });

        return App.Clock.find();
    }
});
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
    {{#each controller}}
    <li>{{city}}, {{country}} - {{time}}</li>
    {{else}}
    You have not defined any clock yet.
    {{/each}}
</ul>
<form {{action "save" on="submit"}}>
    {{view Ember.TextField valueBinding="city" placeholder="City"}}
    <button>Save</button>
</form>
路由器:

App.Clock = DS.Model.extend({
    city: DS.attr('string'),
    country: DS.attr('string'),
    latitude: DS.attr('string'),
    longitude: DS.attr('string'),
    time: DS.attr('date'),
    order: DS.attr('number'),

    start: function() {
        var clock = this;

        var updateTime = function() {
            var timezoneService = Utilities.TimezoneService;

            timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
                clock.set('time', timezoneService.getDateTime(timezone.offset));
            });
        };

        updateTime();

        window.setInterval(function() {
            updateTime();
        }, 1000);
    }
});
App.ClocksView = Ember.View.extend({
  templateName : 'world_clock/clocks'
});

App.ClocksNewView = Ember.View.extend({
  templateName : 'world_clock/new'
});
App.ClocksController = Ember.ArrayController.extend({
    sortProperties: ['order']
});

App.ClocksNewController = Ember.ObjectController.extend({
    city: null,
    save: function() {
        var cityName = this.get('city');
        if(!cityName.trim()){
            return;
        }

        var locationService = Utilities.LocationService.getInstance();

        locationService.lookupLocation(cityName, function(location) {
            var city = location.city;
            var country = location.country;
            var lat = location.latitude;
            var lon = location.longitude;

            if(city && country && lat && lon) {
                var clks = App.Clock.find({ city: city });
                clks.on('didLoad', function() {
                    if(clks.get('length') === 0) {
                        var clock = App.Clock.createRecord({
                            city: location.city,
                            country: location.country,
                            latitude: location.latitude,
                            longitude: location.longitude,
                            order: 10
                        });

                        clock.save();
                    }
                });
            }
        });

        this.set('city', '');

        this.get('target').transitionTo('clocks');
    }
});
App.Router.map(function() {
    this.resource('clocks', { path: '/' }, function() {
        this.route('new');
    });
});

App.ClocksRoute = Ember.Route.extend({
    model: function() {
        var locationService = Utilities.LocationService.getInstance();

        locationService.getLocation(function(location) {
            App.Clock.createRecord({
                city: location.city,
                country: location.country,
                latitude: location.latitude,
                longitude: location.longitude,
                order: -10
            });
        });

        return App.Clock.find();
    }
});
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
    {{#each controller}}
    <li>{{city}}, {{country}} - {{time}}</li>
    {{else}}
    You have not defined any clock yet.
    {{/each}}
</ul>
<form {{action "save" on="submit"}}>
    {{view Ember.TextField valueBinding="city" placeholder="City"}}
    <button>Save</button>
</form>
时钟。把手:

App.Clock = DS.Model.extend({
    city: DS.attr('string'),
    country: DS.attr('string'),
    latitude: DS.attr('string'),
    longitude: DS.attr('string'),
    time: DS.attr('date'),
    order: DS.attr('number'),

    start: function() {
        var clock = this;

        var updateTime = function() {
            var timezoneService = Utilities.TimezoneService;

            timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
                clock.set('time', timezoneService.getDateTime(timezone.offset));
            });
        };

        updateTime();

        window.setInterval(function() {
            updateTime();
        }, 1000);
    }
});
App.ClocksView = Ember.View.extend({
  templateName : 'world_clock/clocks'
});

App.ClocksNewView = Ember.View.extend({
  templateName : 'world_clock/new'
});
App.ClocksController = Ember.ArrayController.extend({
    sortProperties: ['order']
});

App.ClocksNewController = Ember.ObjectController.extend({
    city: null,
    save: function() {
        var cityName = this.get('city');
        if(!cityName.trim()){
            return;
        }

        var locationService = Utilities.LocationService.getInstance();

        locationService.lookupLocation(cityName, function(location) {
            var city = location.city;
            var country = location.country;
            var lat = location.latitude;
            var lon = location.longitude;

            if(city && country && lat && lon) {
                var clks = App.Clock.find({ city: city });
                clks.on('didLoad', function() {
                    if(clks.get('length') === 0) {
                        var clock = App.Clock.createRecord({
                            city: location.city,
                            country: location.country,
                            latitude: location.latitude,
                            longitude: location.longitude,
                            order: 10
                        });

                        clock.save();
                    }
                });
            }
        });

        this.set('city', '');

        this.get('target').transitionTo('clocks');
    }
});
App.Router.map(function() {
    this.resource('clocks', { path: '/' }, function() {
        this.route('new');
    });
});

App.ClocksRoute = Ember.Route.extend({
    model: function() {
        var locationService = Utilities.LocationService.getInstance();

        locationService.getLocation(function(location) {
            App.Clock.createRecord({
                city: location.city,
                country: location.country,
                latitude: location.latitude,
                longitude: location.longitude,
                order: -10
            });
        });

        return App.Clock.find();
    }
});
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
    {{#each controller}}
    <li>{{city}}, {{country}} - {{time}}</li>
    {{else}}
    You have not defined any clock yet.
    {{/each}}
</ul>
<form {{action "save" on="submit"}}>
    {{view Ember.TextField valueBinding="city" placeholder="City"}}
    <button>Save</button>
</form>
{{outlet}
{{{#linkTo“clocks.new”}添加Clock{{/linkTo}
    {{{#每个控制器}}
  • {{城市},{{国家}-{{时间}
  • {{else} 您尚未定义任何时钟。 {{/每个}}
全新。车把:

App.Clock = DS.Model.extend({
    city: DS.attr('string'),
    country: DS.attr('string'),
    latitude: DS.attr('string'),
    longitude: DS.attr('string'),
    time: DS.attr('date'),
    order: DS.attr('number'),

    start: function() {
        var clock = this;

        var updateTime = function() {
            var timezoneService = Utilities.TimezoneService;

            timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
                clock.set('time', timezoneService.getDateTime(timezone.offset));
            });
        };

        updateTime();

        window.setInterval(function() {
            updateTime();
        }, 1000);
    }
});
App.ClocksView = Ember.View.extend({
  templateName : 'world_clock/clocks'
});

App.ClocksNewView = Ember.View.extend({
  templateName : 'world_clock/new'
});
App.ClocksController = Ember.ArrayController.extend({
    sortProperties: ['order']
});

App.ClocksNewController = Ember.ObjectController.extend({
    city: null,
    save: function() {
        var cityName = this.get('city');
        if(!cityName.trim()){
            return;
        }

        var locationService = Utilities.LocationService.getInstance();

        locationService.lookupLocation(cityName, function(location) {
            var city = location.city;
            var country = location.country;
            var lat = location.latitude;
            var lon = location.longitude;

            if(city && country && lat && lon) {
                var clks = App.Clock.find({ city: city });
                clks.on('didLoad', function() {
                    if(clks.get('length') === 0) {
                        var clock = App.Clock.createRecord({
                            city: location.city,
                            country: location.country,
                            latitude: location.latitude,
                            longitude: location.longitude,
                            order: 10
                        });

                        clock.save();
                    }
                });
            }
        });

        this.set('city', '');

        this.get('target').transitionTo('clocks');
    }
});
App.Router.map(function() {
    this.resource('clocks', { path: '/' }, function() {
        this.route('new');
    });
});

App.ClocksRoute = Ember.Route.extend({
    model: function() {
        var locationService = Utilities.LocationService.getInstance();

        locationService.getLocation(function(location) {
            App.Clock.createRecord({
                city: location.city,
                country: location.country,
                latitude: location.latitude,
                longitude: location.longitude,
                order: -10
            });
        });

        return App.Clock.find();
    }
});
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
    {{#each controller}}
    <li>{{city}}, {{country}} - {{time}}</li>
    {{else}}
    You have not defined any clock yet.
    {{/each}}
</ul>
<form {{action "save" on="submit"}}>
    {{view Ember.TextField valueBinding="city" placeholder="City"}}
    <button>Save</button>
</form>

{{view Ember.TextField valueBinding=“city”placeholder=“city”}
拯救
如何从视图中调用模型的start方法

除非在极少数情况下,从视图调用模型方法不是一个好主意。也就是说这是可能的。例如,您可以使用类似didInsertElement的内容:

{{each controller itemViewClass="App.ClockView" emptyViewClass="App.NoClocksView"}}

App.ClockView = Ember.View.extend({
  template: Ember.Handlebars.compile("<li>{{city}}, {{country}} - {{time}}</li>"),
  didInsertElement: function() {
    var clock = this.get('content');
    clock.start();
  }
});

App.NoClocksView = Ember.View.extend({
  template: Ember.Handlebars.compile("You have not defined any clock yet.")
});

非常感谢您非常详细的回答:)我唯一的问题是,既然
TimeZoneService.getTimezone
是一个异步回调,那么偏移量的值不会一直保持为空吗?是的,这是一个很好的观点。Guess时钟应该有一个类似于
positionDidChange
的观测器,在lat/long发生变化时触发。该观察者将调用时区服务并设置偏移量属性。这很有意义。但现在我还有几个问题。[1] 我正在一个
可安装Rails的引擎中构建此应用程序
。由于这个原因,
{{world clock city=“clock.city”…
工作不正常。我如何定义组件的模板路径?[2]
{{{{控制器中的每个时钟}}
不工作,但
{{控制器中的每个时钟}
工作正常。请您向我解释一下好吗?[3]你能给我一个控制器的示例代码吗?不知道为什么每个时钟都不工作。Re:rails,也许ember-rails-gem还不知道组件。现在你可以定义App.WorldClockComponent的模板属性,比如:
template:ember.handlebar.compile(“{city},{country}-{time}”)
Re:控制器代码示例,请参见我的答案: