问题
I'm looking into integrating Ember with an existing Rails application, to take advantage of Ember's bindings, events (didInsertElement, etc.) ...
Now I don't want to transfer my erb views to handlebars, but instead I want to create Ember View objects and attach them to various elements already in the DOM. For example, I might have
<html>
<body>
<div class="header">
</div>
<div class="content">
</div>
<div class="footer">
</div>
</body>
</html>
and (on DOM ready) create a View for each element:
App.HeaderView = Ember.View.create({
// capture $('.header') to this
// console.log(this.$().attr('class')) should then output `header`
});
回答1:
use appendTo() on a view: App.HeaderView.appendTo('.header') see http://jsfiddle.net/yFke9/
UPDATE
I think this is currently not possible. Please proof me wrong! You could create a workaround for this, although this is a hack, see http://jsfiddle.net/jFTk5/. The workaround basically adds the view via append() and inside the didInsertElement callback it replaces the specific element via jQuery's replaceWith.
App.HeaderView = Ember.View.create({
template: Ember.Handlebars.compile('hello from HeaderView'),
classNames: ['header'],
didInsertElement: function() {
Ember.$('.header').replaceWith(this.$());
}
}).append();
If you're going with this solution you could write a Mixin which handles this for you, see http://jsfiddle.net/KFcgA/.
App.ReplaceWith = Ember.Mixin.create({
didInsertElement: function(){
var el = this.get('elementToReplace');
Ember.$(el).replaceWith(this.$());
}
});
App.HeaderView = Ember.View.create(App.ReplaceWith, {
template: Ember.Handlebars.compile('Hello from HeaderView'),
classNames: ['header'],
elementToReplace: '.header'
}).append();
回答2:
Ok the following works but I haven't fully tested it.
Inspired by @pangratz's pull request I extend Ember.View with the following method for
Ember.View = Ember.Object.extend(
/** @scope Ember.View.prototype */ {
// ........
wrap: function(target) {
this._insertElementLater(function() {
// Set all attributes name/values from target
var target_attrs = {};
var $this = this.$();
for (var attr, i=0, attrs=$(target)[0].attributes, l=attrs.length; i<l; i++){
attr = attrs.item(i)
var attrName = attr.nodeName;
var attrValue = attr.nodeValue;
if(attrName === 'id') continue;
$this.attr(attrName, attrValue);
}
// Set HTML from target
$this.html($(target).html());
Ember.$(target).replaceWith($this);
});
return this;
},
// ........
});
Basically it copies the html content of the target element as well as its attributes. Then by just doing
App.HeaderView = Ember.View.create().wrap('.header');
the .header element (that is already in the DOM) is now in App.HeaderView.
See http://jsfiddle.net/KFcgA/4/
来源:https://stackoverflow.com/questions/9617789/create-ember-view-from-a-jquery-object