I have displayed a textbox using Ember.View.
In model i had specified all the details of the input.
App.Display = DS.Model.extend({
inputText: DS.attr('string'),
width: DS.attr('string'),
height: DS.attr('string'),
className: DS.attr('string')
})
App.Display.FIXTURES = [{
id: '1',
innnerText : 'helo',
width: '197px',
height: '25px',
className: 'DisplayClass'
}]
from the model how can i append the className , width,height and innerText to the display unit.
Here is my displayView
<script type="text/x-handlebars" data-template-name="_display">
{{#view 'App.DisplayView'}}{{/view}}
</script>
App.DisplayView = Ember.View.extend({
tagName: 'input',
});
App.DisplayController = Ember.ArrayController.extend({
actions: {
}
});
How to populate the model data (i.e. innerText,dimensions,className) through controller to the view.
Note:Im not using any this.resource('somename')
In IndexRoute i have set the controller
setupController: function (controller, model) {
controller.set('model', model);
this.controllerFor('Display').set('model', model.displayInput);
In IndexRoute
App.IndexRoute = Ember.Route.extend({
model: function(){
return {
//findall of model name
displayInput : this.store.findAll('display')
}
}
Now to use model to set and get the value of input
Working demo on JS Bin. You're using views - deprecated feature now - instead of components, which make code look not very nice and it's not ideal tool to implement behaviour you want. Instead I converted your approach to use components. Also, in Fixtures you've defined innnerText instead of inputText.
So, let's start with component. Code:
App.DisplayComponentComponent = Ember.Component.extend({
tagName: 'input',
attributeBindings: ['style', 'value'],
style: Ember.computed('model', 'model.{width,height}', function() {
var ret = '',
width = this.get('model.width'),
height = this.get('model.height');
if (width) {
ret += 'width: ' + width + ';';
}
if (height) {
ret += 'height: ' + height + ';';
}
return ret;
})
});
Component template:
<script type="text/x-handlebars" data-template-name="display-component">
</script>
Then, correct fixtures:
App.Display.FIXTURES = [{
id: '1',
inputText : 'helo',
width: '197px',
height: '25px',
className: 'DisplayClass'
}];
There's also a problem with your model. I think it'll be easier to initialize model for display controller just in setupController model.
setupController: function (controller, model) {
controller.set('model', model);
this.store.findAll('display').then(function(displays) {
this.controllerFor('display').set('model', display.get('firstObject'));
});
}
Then, if you want to use it, do it like that(I'm using your example with _display template, but I don't have a clue how do you use this):
<script type="text/x-handlebars" data-template-name="_display">
{{display-component model=model class=model.className value=model.inputText}}
</script>
I have to assume that _display template is for display controller, because you're question isn't clear at all.
Related
I have Marionette/Backbone appliaction which is working fine. I wanted to add extra layer in our views:
Before:
TabLayoutView -> CompositeView
After:
TabLayoutView -> SectionLayoutView -> CompositeView
But this is not working and I can't see where is the problem.
Here is the code:
Model of tab:
TabModel = Backbone.Model.extend({
defaults: {
headerModel: {label: '', left: '', right: ''}
}
})
Template of tab:
<div class="headerSection"></div>
View of tab:
var TabLayoutView = Marionette.LayoutView.extend({
template: _.template(TabTemplate),
tagName: 'div',
regions: {
headerRegion: {selector: '.headerSection'}
},
onShow: function() {
this.headerRegion.show(new SectionLayoutView({model: this.model.get('headerModel')}));
}
});
Model of section:
SectionModel = Backbone.Model.extend({
defaults: {
label: '',
left: '',
right: ''
}
});
Template of section:
<div class="section">
<div class="leftSection"/>
<div class="rightSection"/>
</div>
View of section:
SectionLayoutView = Marionette.LayoutView.extend({
template: _.template(SectionTemplate),
tagName: 'div',
regions: {
leftRegion: {selector: '.section .leftSection'},
rightRegion: {selector: '.section .rightSection'}
},
onShow: function() {
this.leftRegion.show(new CompositeView(this.model.get('left')));
this.rightRegion.show(new CompositeView(this.model.get('right')));
}
});
Error I get is :
Uncaught TypeError: Cannot read property 'apply' of undefined
in the method
serializeModel: function(model) {
return model.toJSON.apply(model, _.rest(arguments));
}
which is triggered in this line:
this.headerRegion.show(new SectionLayoutView({model: this.model.get('headerModel')}));
Could you please give me any ideas of what is wrong? We have similar code in other places and it is working fine. It seems like there is a problem with parsing model to json, but I can't see why.
Because are you passing a plain Object to the view...
this.headerRegion.show(new SectionLayoutView({
model: this.model.get('headerModel') // NOT a Backbone.Model
});
Try this:
this.headerRegion.show(new SectionLayoutView({
model: new Backbone.Model(this.model.get('headerModel'))
});
I'm trying to figure out how to fetch data with Ember Data and render. After several problems I got to this point where I get no error on the console but the store is empty after the data is loaded.
window.App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
model: function(){
return this.store.find('games');
}
});
App.GamesModel = DS.Model.extend({
name: DS.attr('string')
});
App.GamesAdapter = DS.RESTAdapter.extend({
host: 'http://private-0f6a1-ember37.apiary-mock.com'
});
App.GamesSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload){
var result = { games: payload };
return result;
}
});
And this is the template:
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each model}}
<li>{{name}}</li>
{{/each}}
</ul>
</script>
Here is the link for the code on CodePen: http://codepen.io/tarmann/pen/GJMJxq
I also tried different versions of Ember Data and Ember but with no luck.
Your problem is pluralization: you specify GamesModel instead of GameModel, you find games instead of game etc. I changed all these occurences to be aligned with what Ember expects(and you can read more about Ember standards in guides) and it works, CodePen:
App.IndexRoute = Ember.Route.extend({
model: function(){
return this.store.find('game');
}
});
App.GameModel = DS.Model.extend({
name: DS.attr('string')
});
App.GameAdapter = DS.RESTAdapter.extend({
host: 'http://private-0f6a1-ember37.apiary-mock.com'
});
// https://www.youtube.com/watch?v=HL2bMjndviE
App.GameSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload){
var result = { games: payload };
return result;
}
});
App.IndexController = Ember.Controller.extend({
init: function(){
this.store.push('game', {
id: 100,
name: "Added from controller"
});
}
});
Screenshot with results:
I have this Layout View:
var appLayoutView = Backbone.Marionette.LayoutView.extend({
template: function() {
return "some template string";
},
regions: {
notify: "[data-region='Notify']"
},
onShow: function() {
this.regions.notify.show(new notifyView());
}
});
Which I call like so:
mainLayout.app.show(appLayout);
So ideally, I'd like, when I run the above line (essentially when the layout view is put into the DOM) for the notifyView to be rendered into the "notify" region. However this.regions.notify is just a string. How can I achieve what I'm trying to do here? Basically having the render logic for "notify" inside the Layout View class, and not controlled from the invocation line.
I can't find any docs that show where this got added, but LayoutView should have a getRegion method :
https://github.com/marionettejs/backbone.marionette/blob/master/src/marionette.layoutview.js#L74
so your code would look like :
var appLayoutView = Backbone.Marionette.LayoutView.extend({
template: function() {
return "some template string";
},
regions: {
notify: "[data-region='Notify']"
},
onShow: function() {
this.getRegion('notify').show(new notifyView());
}
});
I’m doing a very basic application with Ember and Ember Data.
For some reason I always have the same problem. My application renders and displays the data correctly, but if I remove and search, it doesn't update the view.
I’ve already asked this here—the link has more code examples—but with not much luck. Here is how I’m trying to do it:
App = Ember.Application.create({
LOG_TRANSITIONS: true, LOG_VIEW_LOOKUPS: true
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Sample = DS.Model.extend({ name: DS.attr('string') });
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('sample');
}
});
App.IndexController = Ember.ArrayController.extend({
actions: {
remove: function(sample) {
sample.destroyRecord();
}
}
});
App.Sample.FIXTURES = [
{ id: 1, name: 'Learn Ember.js'},
{ id: 2, name: 'Record 2' },
{ id: 3, name: 'Test Delete' }
];
App.ApplicationRoute = Ember.Route.extend({
actions: {
showModal: function(name, content) {
this.controllerFor(name).set('content', content);
this.render(name, {
into: 'application',
outlet: 'modal'
});
},
removeModal: function() {
this.disconnectOutlet({
outlet: 'modal',
parentView: 'application'
});
}
}
});
App.MyModalComponent = Ember.Component.extend({
actions: {
ok: function() {
this.$('.modal').modal('hide');
this.sendAction('ok');
}
},
show: function() {
this.$('.modal').modal().on('hidden.bs.modal', function() {
this.sendAction('close');
}.bind(this));
}.on('didInsertElement')
});
From your code I have tried to come up with a reasonable solution for your problem
Before I get into the solution I think the controller should be IndexController rather than sampleDeleteModalController because ember expects controller to have same name as the route.
App.SampleDeleteModalController = Ember.ObjectController.extend({
actions: {
remove: function() {
// Two ways
this.get('model').destroyRecord();
this.transitionToRoute('index');
}
}
});
transitionToRoute from the same route will not refresh a view.This will work only when you want to redirect to another route.
Solution to refresh view
option 1 : you can capture the same action inside index route after removing the record you can do this.refesh() which refreshes the model.
option 2 : You have to explicitly update the binded model inside the controller.
actions: {
remove: function() {
// Two ways
var localCopy = this.get('model');
localCopy.destroyRecord();
this.set('model',localCopy);
}
}
option 3 : After you set your model your model and then do this.rerender().Which is almost equivalent to window.reload()
New to ember here and I thought if you bind the data between view and model then both side will sync up if one changed.
Currently I have my model setup with Emberfire which returns an array of colors:
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return EmberFire.Array.create({
ref: new Firebase("https://ember-starter.firebaseio.com/shape")
});
},
setupController: function(controller, model) {
controller.set('model', model);
}
});
My template is setup as such:
<button {{action "add"}}>Draw</button>
{{#each controller}}
{{#view App.ShapeView contentBinding="content"}}
<div>{{color}}</div>
{{/view}}
{{/each}}
I have a button to add new color to the array:
App.ApplicationController = Ember.ArrayController.extend ({
actions: {
add: function() {
var newColor = {
color: "#222222"
};
this.pushObject(newColor);
}
}
});
Within the view I setup a click action to set the color property:
App.ShapeView = Ember.View.extend({
click: function() {
var self = this;
var changeColor = self.set('context.color', '#121212');
}
});
With the current setup, I'm able to fetch/display a list of colors and change the color to #121212 upon click. However the data doesn't persist to the model(firebase). I'm wondering if I did something wrong or there are better ways to save/sync changes between view and model.
thanks in advance!
May be it is because you have a typo in your add function... this.pushObject(newColore); should be this.pushObject(newColor);
add: function() {
var newColor = {
color: "#222222"
};
this.pushObject(newColor);
}
Good luck