Backgrid is rendering
<table class="backgrid"></table>
but nothing else. Breakpoints in Backgrid:render() are not reached. I'm a Backbone newbie adapting someone else's code and so am not sure exactly what should be happening but LayoutManager:render() is called..it just never seems to get to Backgrid... The data I want to display are being fetched and look as if they are in the right format...but have to admit that it's difficult to tell once they've been wrapped up in a Backbone collection. Any pointers for how to debug/why Backgrid's render is not being called gratefully received.
Code below:
ListenView.js
define([
'backbone',
'underscore',
'backgrid',
'app/models/PersonModel',
'app/collections/PersonCollection',
'app/views/PersonListView',
'hbs!app/templates/listen_template'
],
function(
Backbone,
_,
Backgrid,
Person,
PersonCollection,
PersonListView,
listenTemplate
) {
App = window.App || {};
var ListenView = Backbone.View.extend({
template: listenTemplate,
initialize: function(params) {
//fetch the list of seen people
this.model.attributes.seenPeople.fetch( {
success: function(coll, resp) {
//console.log(coll);
}
});
},
afterRender: function() {
//initialise person view
console.log("creating Backgrid");
this.seenPeopleView = new Backgrid.Grid({
columns: [{
name: "email",
label: "Email",
cell: "string"
},{
name: "id",
label: "ID",
cell: "integer"
}, {
name: "title",
label: "Title",
cell: "string" }
],
collection: this.model.attributes.seenPeople
});
this.seenPeopleView.render();
$('#seen-people-list').append(this.seenPeopleView.el);
}
On the success method from the fetch you should call afterRender.
var self=this;
this.model.attributes.seenPeople.fetch( {
success: function(coll, resp) {
self.afterRender();
}
});
Instead of creating backgrid instance in view (this.seenPeopleView) create instance as
var grid = new Backgrid.Grid({...<your columns and collection related code>..});
Then Render the grid and attach the root to your HTML document as
$('#seen-people-list').append(grid.render().el);
Hope it will work :)
Related
I have a Kendo HierarchicalDataSource object bound to a Kendo treeview widget.
The HierarchicalDataSource simply returns a one-level-deep json formatted object, but for some reason it won't render in the treeview. It just shows the top node "Dimensions", but renders no data when expanded.
Here is my plunk treeview sample , which contains index.html and script.js .
FYI for script.js :
$scope.dimenDataSource is the Kendo HierarchicalDataSource object which uses the transport property to call my method getDimensionsFromServer2 and also specify the schema.
Another FYI: In getDimensionsFromServer2() I have two ways of returning my test data. The dataFlat var returns a flat array, which renders fine. The data object has nested data, but does NOT render in treeview.
I'm not sure what's going wrong.
Thank you,
Bob
**** UPDATE ****
The problem was the incorrect placement of the schema setting (see my answer):
settings.dimenDataSource = new kendo.data.HierarchicalDataSource({
transport: {
read: function(options){
datacontext.getDimensionsFromServer().then(function (data) {
var rootnode = [{ name: "Dimensions", items: data.data }];
options.success(rootnode);
});
},
schema: {
model: { children: "items" }
},
loadOnDemand: false
}
});
My mistake was in the schema placement, which I had inadvertently placed in the transport option. It should placed at the same level, not within it.
Here's is the corrected version:
settings.dimenDataSource = new kendo.data.HierarchicalDataSource({
transport: {
read: function(options){
datacontext.getDimensionsFromServer().then(function (data) {
var rootnode = [{ name: "Dimensions", items: data.data }];
options.success(rootnode);
});
},
loadOnDemand: false
},
schema: {
model: { children: "items" }
}
});
I'm pretty new with Backbone and I'm struggling with Backbone.Collection :
I have a list of products in different categories (shoes, shirts, pants, ...). The idea is when an user clicks on a category, I'm updating URL in my Collection (ex : datas/shoes.json becomes datas/shirts.json) and do a collection.fetch() in order to render my new list.
It's actually working but I don't know why it's continually triggering "add", "remove" events. This is my code, let me know if you see something strange :
define([
"backbone",
],
function(Backbone)
{
var ProductsView = Backbone.View.extend({
el: "#products",
initialize:function(){
_.bindAll(this,"addItem","removeAll");
this.populate();
},
populate:function(){
this.collection = new ProductCollection();
this.listenTo(this.collection, 'add', this.addItem);
this.listenTo(this.collection, 'remove', this.removeAll);
this.collection.fetch();
},
addItem(todo){
var view = new ProductItemView({model: todo});
this.$el.append(view.render().el);
},
removeAll:function(){
this.$el.children().remove();
this.collection.url = "datas/shoes.json";
this.collection.fetch();
},
});
return ProductsView;
});
This is my collection
define([
"backbone",
"models/modules/products/ProductModel"
],
function(Backbone, ProductModel)
{
var ProductsCollection = Backbone.Collection.extend({
model : ProductModel,
url : "datas/shirts.json",
parse: function(response){
return response.products;
},
});
return ProductsCollection;
});
Thanks for your help guys !!
Let me know if it's not clear, I'll try to clarify that.
it's definitely helpful to give up, go to bed, in order to take a step back.
So I've read the documentation and found reset method :
remove:function(todo){
this.$el.children().remove();
this.collection.reset();
this.collection.url = "datas/shoes.json";
this.collection.fetch();
},
I am using Restangular to resolve an response (a list of products)...I know this is being resolved OK.
I am new to Kendo-UI. But have set up a basic test grid as below. I am using k-rebind, as the products array is likely not resolved at the time the grid is created.
<kendo-grid k-options="mainGridOptions" k-rebind="products"></kendo-grid>
In my controller:
$scope.products = [];
$scope.therapyAreas = [];
$scope.dropDownTAs = [];
prProductService.getProducts().then(function(products) {
$scope.products = products;
prTAService.getTAs().then(function(tas) {
$scope.therapyAreas = tas;
for(var i = 0; i < $scope.therapyAreas.length;i++) {
$scope.dropDownTAs.push({id: $scope.therapyAreas[i].id, therapyArea: $scope.therapyAreas[i].therapyArea});
}
});
});
$scope.mainGridOptions = {
dataSource: {
data: $scope.products
},
height: 550,
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
"productName",
"activeIngredients",
"productComments",
"gpt",
"ta"
]
};
}])
I know the products array is being returned, and I would have thought k-rebind would watch the products array for changes so when it is resolved it refreshes the UI...no such luck.
I have tried bashing in a manual array into the data source to mirror the response for the products array, and the grid works fine.
Regards
i
You are absolutely correct that the Kendo UI Grid will initially not have access to the data, so when the Grid gets rendered on the page it will simply bind to an empty array - giving you no data. You're also correct to use the k-rebind attribute in this scenario, since it should keep an eye out for when the scope changes.
However, one important thing that you missed is that k-rebind should be set to the same as your options, as mentioned in this documentation article. This can easily be missed, but I've used this before in similar scenarios.
So, while I haven't tested this I believe the following should work for you:
<kendo-grid k-options="mainGridOptions" k-rebind="mainGridOptions"></kendo-grid>
i got the same error. But this worked for me:
in the html view code:
<kendo-grid data-source="vm.kendoData.data"
sortable="true"
options="vm.gridOptions">
</kendo-grid>
in the angular controller:
vm.kendoData = new kendo.data.DataSource({});
vm.getRegistros = function () {
vm.loading = true;
registroDePontoService.registrosPorPeriodo(vm.registroPorPeriodo)
.success(function (result) {
vm.kendoData.data = result.registros;
}).finally(function () {
vm.loading = false;
});
};
vm.gridOptions = {
columns: [{
field: "date",
title: "Date",
width: "120px"
}, {
field: "column1",
title: "column1",
width: "120px"
}, {
field: "column2",
title: "column2",
width: "120px"
}]
I would like to reload items in the carousel onPainted() method. So whenever users come the carousel item then we have a fresh list of carousel items. Problem at this point of time (please have a look at the source code), the carousel reloads items, however until I touch the carousel, the first carousel item is blank (or not selected) and no items selected. I would like at least to see the first element to be selected.
So here is the simplified source code:
Ext.define("APN.view.FeaturedCarousel", {
config: {
listeners: {
painted: function(carousel, eOpts) {
var features_url = Ext.getStore("regionalisation").getRegionalisedMenus().feature.url;
this.setCarouselStore(features_url);
}
}
},
initialize: function () {
this.callParent();
var me = this;
var features_url = Ext.getStore("regionalisation").getRegionalisedMenus().feature.url;
this.setCarouselStore(features_url);
},
setCarouselStore: function (features_url) {
var me = this;
Ext.Ajax.request({
url: features_url,
success: function (response) {
me.removeAll();
if (!xml) return;
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
fields: [
],
data: xml,
proxy: {
type: 'memory',
reader: {
type: 'xml',
rootProperty: 'xml',
record: 'item'
}
}
});
store.each(function (record) {
var item = Ext.create("Ext.Container", {
html: "some HTML HERE"
});
me.add(item);
});
}
});
}
});
I think you should activate the first item in the carousel once all the items are added. Like this:
store.each(function (record) {
var item = Ext.create("Ext.Container", {
html: "some HTML HERE"
});
me.add(item);
});
me.setActiveItem(0);
This should make the first item selected.
If you want to change the carousel content every time it is activated, use "active" listener. Because "painted" will be called only once and if you want that, then no point in adding a painted event because you are already calling the "setCarouselStore" function in "initialize" method.
I'm trying to get Store in the view on the init of the applicatoin, however the console tells me: Object #<Object> has no method 'getStore'
I'm wondering how would you get a store in this sequence:
Initialise app
Get user GPS location
Create a store
Display view with the store
init: function () {
this.callParent();
console.log("controller init");
},
launch: function () {
this.getApplicationSettings();
this.getApplicationRegionalisation();
Ext.getStore("appSettings").setValue("region", "Melbourne");
var store = Ext.create("APN.store.Locations");
var geo = Ext.create('Ext.util.Geolocation', {
autoUpdate: false,
listeners: {
locationupdate: function(geo) {
var location = store.getClosestLocation(geo.getLatitude(), geo.getLongitude());
Ext.getStore("appSettings").setValue("region", location.get("location"));
},
locationerror: function(geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
}
}
});
And then in the view I would like to call something like this, correct me if I'm doing a stupid thing:
requires: [
'APN.store.AppSettings'
],
..... omitted stuff
// in items:
items: [
{
itemId: 'nav_home',
id: 'homeView',
group: '',
title: "Home",
layout: 'vbox',
slideButton: { selector: 'toolbar' },
settingsButton: { selector: 'toolbar' },
items: [{
xtype: 'articlelist',
id: 'latestNews',
category: 'Latest',
feedUrlName:
// here is the place where it bugs out!
Ext.getStore("appSettings").getValue(Ext.getStore("appSettings").getValue("region").get("menuItems").home.url,
}
],
},
Wherever you are creating the view, you can create the store before that and set store to the view explicitly so that when initialize function is executed it will get this.config.store. To get GPS location on app initialization, you can get location in Launch function of Ext.application before even creating the store and view. If you want to create view only after store data is loaded, you should create view in load callback of store.
I hope this is what you were looking for, if not please add some code to your question so that we can comment on specifics.