I have a Backbone View and I want restart it. The view prints a table with prices but when the user push a check, the prices have that change.
I don't know restart my backbone View.
GrillaView = Backbone.View.extend({
events : {
// events
},
initialize : function(){
// templates
},
render : function (){
this.$el.removeClass('hidden');
this.renderQuote();
},
setCategories : function (collection){
// Print a template
},
addResult : function (item){
// Print other template
},
setPrice : function (prov,item){
// prices
},
filterFuel : function(e){
// Here I need restart the View
}
Totally unclear question but I assume you want to rerender when new data are available. So when new data are here you'll trigger this.render(); inside your view.
the render function should get its data from a model, when the model is updated you trigger render(). It's that simple. But without more code it's hard to tell what's your problem.
let me know if it helps.
Related
I am having trouble working out if it is possible to pass a string into a view using backgone.history.loadUrl?
//My current method of reloading the view
Backbone.history.loadUrl(Backbone.history.fragment);
I would like to use this method if possible so that it renders the view from the Backbone router rather then rendering my view again from within itself and passing it in as the options for that view.
//Destroy old view
//Render view again
var view = new myView("success msg");
Here's a simple way to extend Backbone.history with a reload function:
_.extend(Backbone.history, {
reload: function(){
return this.loadUrl(this.getFragment());
}
});
Don't do this if you're writing a library/plugin.
Then calling Backbone.history.reload(); anywhere will call the route again.
Is it a good way to re-render a view? No.
If you want to re-render a view within itself, do that, don't reload the whole route.
var View = Backbone.View.extend({
// events, etc. ...
render: function() {
// rendering
if (this.success) {
// show success message
}
return this;
},
onMyEvent: function() {
// here, a re-render with a success message is necessary
this.success = true;
this.render();
}
})
Consider the following JS:
var ChildLayout = Marionette.Layout.extend({
template: "... let's not go here ...",
initialize: function() {
console.log('Child Layout Initialized'); // registers once
},
onRender: function() {
console.log('Rendered'); // registers 2 times
},
});
var ParentLayout = Marionette.Layout.extend({
template: "<div class='child-region'></div>",
regions: { childRegion: '.child-region' },
onRender: function() {
console.log('About to initialize ChildLayout'); // registers once
this.childRegion.show(new ChildLayout());
},
});
In the above, I use the ParentLayout to render the ChildLayout in one of its Regions. Notice that I do not pass any sort of model to the ChildLayout.
The show function, a property of Marionette, should logically initialize and then render the model once. A Marionette View should not re-render itself unless there is some change in its model, from what I understand.
In my application, the onRender of ChildLayout is triggering in my code several times, though its initialize only triggers once.
I cannot see what is causing Marionette to render the ChildLayout multiple times - this does not make sense.
Any insight?
edit
On inspecting the source code of Marionette.js, the show function clearly only renders the passed view once, right after initializing. So the re-renders could only occur from the Layout deciding autonomously to re-render. Interesting.
This turned out to be my own problem with a Zombie View, which I since handled.
I am using a window view in Enyo, which basically fetches data from database, and based on the no. items fetched, multiple buttons are created dyanamically. On click of any of the button, an another call to database is made to fetch other set of items. The fetched items need to be added dyanamically to a <ul> item as buttons. Which is done by the code -
testPOSView : function(inSender, inEvent) {
var data = inEvent.data;
console.log(data.tables);
enyo.forEach(data.tables, function(table) {
console.log(table);
this.$.sectiontablebar.createComponent({
kind : 'OB.OBPOSPointOfSale.UI.TablesButton',
button : {
kind : 'OB.UI.Section',
content: table.tableName,
id: table.tableId
}
});
}, this);
}
But when i click on the button, i am getting the results from DB, but they are not added to the sectiontablebar component.
The complete code of the file is available # https://gist.github.com/sangramanand/ad665db9cd438001254a
Any help would be appreciated. Thanks!!!
I'm not certain this is the way to do it, but when I create subcomponents dynamically, I add this.render() to the end of the function. This renders the component, thus showing the dynamically added content.
If I were to rewrite your code I would do it like this:
testPOSView : function(inSender, inEvent) {
var data = inEvent.data;
enyo.forEach(data.tables, function(table) {
// create the sub-component in "this"
this.createComponent({
// and assign the container
container: this.$.sectiontablebar,
kind : 'OB.OBPOSPointOfSale.UI.TablesButton',
button : {
kind : 'OB.UI.Section',
content: table.tableName,
id: table.tableId
}
});
}, this);
this.render();
}
More than likely you are losing the pointer to this when testPOSView is running after an async call to get the db results.
In your anythingTap function (see gist, readers) you might try binding the function you're sending to OB.DS.Process:
this.bindSafely(function(data) {me.doTestPOSView();}))
By the way, you can probably eliminate all that me = this tomfoolery if you bind your functions properly.
I have a Backbone collection model (with sub-models as elements)
and views to edit it.
I would like it that when the model is initially created, to "turn off"
sync, so the back end is never invoked until the user clicks on a
button, then I would like to "turn on" the sync, and invoke the save
method on the root model, in order to save it to the DB.
Once a model it saved, it should behave like a normal model.
The goal is to avoid saving until the user determines that he is happy with
what he has entered.
Backbone will initially look for a model's local sync function before going to Backbone.sync.
Backbone.js Documentation: The sync function may be overriden globally as Backbone.sync, or at a finer-grained level, by adding a sync function to a Backbone collection or to an individual model.
Therefore you can do this:
var MyModel = Backbone.Model.extend({
// New instances of this model will have a 'dud' sync function
sync: function () { return false; }
});
var MyView = Backbone.View.extend({
...
events : {
'click #my-button' : 'enableSync',
'click #my-save-button' : 'saveModel'
},
enableSync: function () {
// If this view's model is still pointing to our fake sync function,
// update it so that it references Backbone.sync going forward.
if (this.model.sync !== Backbone.sync) {
this.model.sync = Backbone.sync;
}
},
saveModel: function () {
// This won't actually do anything until we click '#my-button'
this.model.save();
}
...
});
var view = new MyView({ model: new MyModel() });
In my app i have a few tagList, each one contains a few tags grouped by index_name.
I'm lost on how should i handle that with Backbone views.
I have a TagListView that extends Backbone.View, i guess i'll handle all events with this view.
My main question i : should i create a TagView with a render function that would be created & rendered for each tag in the TagListView render function ?
Here is what i do so far in my view : (is this ok for initialization ?!)
<ul id="strategy-tags">
<!-- initial data -->
<script type="text/javascript">
AppData.strategyTagList = $.parseJSON('<?php echo json_encode($strategyTagList); ?>');
strategyTagListView = new App.TagListView({el : "#strategy-tags", data: AppData.strategyTagList});
</script>
</ul>
Inside my core.js :
App.TagListView = Backbone.View.extend({
// dom event specific to this item.
events: {
},
initialize: function(options) {
this.el = options.el;
},
render: function() {
// let's construct the tag list from input data
_.each(options.data, function(index) {
// render index? <-- how ?
_.each(index, function(tag) {
// render tag? <-- how ?
console.log(tag);
});
});
return this;
}
});
Thanks a lot.
I would say yes, the benefit of the individual 'item' view being able to re-render individually is that if you make changes to the model behind such an item, only that item will need to be re-rendered by the browser. Which is best for performance.
It seems to be a question of granularity here, and one I've asked myself on occasion. My advice would be not to over do the views. It is akin to creating objects for everything in java - sometimes a simple string will suffice. If you find a case of increased granularity in the future you can always come back and change it.