backbone.js - problem loading using models defined in separate file - sinatra

I'm running Sinatra with Backbone.js. I'm trying to split up my models, views, etc so they aren't all lumped into a single JS file. Right now I have the following.
index.html
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<script src="scripts/underscore-min.js"></script>
<script src="scripts/jquery-1.5.min.js"></script>
<script src="scripts/backbone-min.js"></script>
<script src="scripts/models.js"></script>
...
models.js
Models = {
var Event = Backbone.Model.extend({
});
var Events = Backbone.Collection.extend({
url: '/events',
model: Event
});
};
So models.js expects that Backbone.js has been loaded, which it should have been based on index.html, however, I'm getting a JavaScript error in models.js where I reference Backbone.Model.
Any ideas on what I'm missing here?

That isn't valid javascript. Something like this is more likely to work :
Models = {}
Models.Event = Backbone.Model.extend({
});
Models.Events = Backbone.Collection.extend({
url: '/events',
model: Event
});

Related

Extending SAPUI5 Applications

I tried to acquaint myself with extending SAPUI5 Applications. To do this I used the splitapp in the folder test-resources/sap/m/demokit
As specified in the Developer Guide - Extending SAPUI5 Applications you only have to create the Component.js for a the custom application project. Now there are 2 questions:
How can you bootstrap the extended Application without having a index.html?
How do you solve relative path-problems (e.g inside the function createContent)?
My current solution is to copy the index.html from the splitapp, paste it into splittapp-ext and modify all the paths...but this solution doesn't seems to be very modular:
original index.html (splitapp):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta charset="UTF-8">
<title>'sap.m.SplitApp' Demo Application</title>
<script id='sap-ui-bootstrap' type='text/javascript'
src='../lib/openui5/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.m'
data-sap-ui-resourceroots='{
"res": "./",
"sap.ui.demo.splitapp" : "./",
"view" : "./view",
"model" : "./model",
"util" : "./util"
}' >
</script>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script>
new sap.m.Shell("Shell", {
title : "sap.m splitapp",
showLogout : false,
app : new sap.ui.core.ComponentContainer({
name : 'sap.ui.demo.splitapp'
}),
homeIcon : {
'phone' : 'img/57_iPhone_Desktop_Launch.png',
'phone#2' : 'img/114_iPhone-Retina_Web_Clip.png',
'tablet' : 'img/72_iPad_Desktop_Launch.png',
'tablet#2' : 'img/144_iPad_Retina_Web_Clip.png',
'favicon' : 'img/favicon.ico',
'precomposed': false
}
}).placeAt('content');
</script>
</head>
<body class='sapUiBody' id="content">
</body>
</html>
modified index.html (splitapp-ext):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta charset="UTF-8">
<title>'sap.m.SplitApp' Demo Application</title>
<script id='sap-ui-bootstrap' type='text/javascript'
src='../lib/openui5/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.m'
data-sap-ui-resourceroots='{
"res": "../splitapp",
"sap.ui.demo.splitapp" : "../splitapp",
"view" : "../splitapp/view",
"model" : "../splitapp/model",
"util" : "../splitapp/util"
}' >
</script>
<link rel="stylesheet" type="text/css" href="../splitapp/css/style.css">
<script>
new sap.m.Shell("Shell", {
title : "sap.m splitapp",
showLogout : false,
app : new sap.ui.core.ComponentContainer({
name : 'sap.ui.demo.splitapp'
}),
homeIcon : {
'phone' : 'img/57_iPhone_Desktop_Launch.png',
'phone#2' : 'img/114_iPhone-Retina_Web_Clip.png',
'tablet' : 'img/72_iPad_Desktop_Launch.png',
'tablet#2' : 'img/144_iPad_Retina_Web_Clip.png',
'favicon' : 'img/favicon.ico',
'precomposed': false
}
}).placeAt('content');
</script>
</head>
<body class='sapUiBody' id="content">
</body>
</html>
For the 2. question I do not have a modular solution.
The anonymous function createContent inside Component.js of the splitapp defines a relative path to the JSON-models. The models cant't be found inside the splitapp-ext Application. The only way I found is to modify the Component.js:
createContent : function () {
// create root view
var oView = sap.ui.view({
id : "app",
viewName : "view.App",
type : "JS",
viewData : { component : this }
});
// --> WORKAROUND: add the module path to the JSON-paths
var rootPath = jQuery.sap.getModulePath("sap.ui.demo.splitapp");
// set navigation model
// load the global data model
var oJSONDataModel = new sap.ui.model.json.JSONModel(rootPath + "/model/data.json");
oView.setModel(oJSONDataModel);
// load the global image source model
var oImgModel = new sap.ui.model.json.JSONModel(rootPath + "/model/img.json");
oView.setModel(oImgModel, "img");
// done
return oView;
}
Is there a better way to extend a SAPUI5 Application?
You can try the extension of an app using SAP Web IDE . You can find the trial links on SAP SCN . The whole idea of Component based approach is to enable the applications to be launched in a broader context such as a Fiori Launchpad . If you want to test it locally, you might consider setting up a local launchpad sandbo from this link:
Set up local Fiori Launchpad.
It is possible to run a local test version of launchpad (with limitations).
first three search results
detailed wiki
As for the second question, remember that control is looking for a model matching the bind path inside on itself, later on parents, and bubbling up to the core. So, setting a model to one view is not best option. You can set model directly to the Component.js as whole application have access there, or just for testing, to the core - sap.ui.getCore().setModel(myModel).
This is an example from ui documentation of proper definition of Component.js with assigned models (for version 1.30, for previous ones you probably won't use 'define'):
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"sap/ui/model/resource/ResourceModel"
], function (UIComponent, JSONModel, ResourceModel) {
"use strict";
return UIComponent.extend("sap.ui.demo.wt.Component", {
metadata : {
manifest: "json"
},
init : function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// set data model
var oData = {
recipient : {
name : "World"
}
};
var oModel = new JSONModel(oData);
this.setModel(oModel);
// set i18n model
var i18nModel = new ResourceModel({
bundleName : "sap.ui.demo.wt.i18n.i18n"
});
this.setModel(i18nModel, "i18n");
}
});
});
Similar sample documented in openui5 you can find here:
component and model sample

How can I generate pages in Assemble based on an different json files?

So I have a folder rules that that looks like this:
rule-001.json
rule-002.json
rule-003.json
Each *.json file is of a unified format:
{ name: 'AAA', descriptions: 'BBB' }
How can I generate a pages based on these files in Assemble?
The short answer is that you need to load your JSON data in your Gruntfile and use it to replace the Assemble pages object.
I have written a blog post about generating pages from data, based on the Assemble Blog Theme sample. In both cases, the pages data was stored in a single JSON file.
In your case, you need to load the data from all of JSON files in your Gruntfile, and transform the data into the pages format. You can do this any number of ways, but one simple way would be to write a function in your Gruntfile that does this:
function loadDataPages (jsonFileSpec) {
var path = require("path");
var jsonPaths = grunt.file.expand(jsonFileSpec);
var jsonPages = jsonPaths.map(function (jsonPath) {
var jsonData = grunt.file.readJSON(jsonPath);
var outputFileName = path.basename(jsonPath, path.extname(jsonPath)) + ".html";
var jsonPage = {
"data": jsonData,
"content": "This is the body content for page " + outputFileName,
"filename": outputFileName
};
return jsonPage;
});
return jsonPages;
}
and then you need to load this data object in your Grunt config and pass it to Assemble's pages option:
grunt.initConfig({
assemble: {
data: {
options: {
flatten: true,
layout: "source/templates/layouts/custom-data-layout.hbs",
pages: loadDataPages("source/custom-data/*.json")
},
files: {
"output/custom-data-pages/": ["source/custom-data/index.hbs"]
}
}
}
// ...
});
Here is what the layouts might look like:
custom-data-layout.hbs
<!DOCTYPE html>
<html>
<head>
<title>Custom Data - {{name}}</title>
</head>
<body>
<h1>Custom Data - {{name}}</h1>
<p>{{ description }}</p>
{{> body }}
</body>
</html>
index.hbs
---
layout: false
title: Custom Data Index
---
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<ul>
{{#each pages }}
<li>{{basename}}</li>
{{/each}}
</ul>
</body>
</html>
Something like this should work for you. You just create separate Assemble tasks and call the main Assemble task with grunt.
https://gist.github.com/davidwickman/a0bf961e3099ea6b9c35

Unable to Execute Jquery from sidebar in Addon Firefox SDK

I am new to this Firefox SDK , but what i have understood you can execute content Scripts on Pages.
Here is the Code
MAIN.JS
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: data.url("index.html"),
onReady: function (worker) {
worker.port.emit('turl',tabs.activeTab.url);
}
});
SIDEBAR.JS
$('#bt1').on('click',function(){
$('title').textContent;
});
INDEX.HTML
<!DOCTYPE HTML>
<html>
<body>
<input type="button" id="bt1" value="Click Me"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="sidebar.js"></script>
</body>
</html>
But this code tries to find out title of the Sidebar html.
I have also tried using contentScriptFile in Main.js but same thing happened
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: data.url("index.html"),
contentScriptFile: [data.url("jquery.min.js"),data.url("sidebar.js")],
onReady: function (worker) {
worker.port.emit('turl',tabs.activeTab.url);
}
});
The Jquery code is in the sidebar.js
Still no Results.Please help
There is no contentScriptFile for the Sidebar class.
Try this: copy the jquery library to a local file in the data folder, then refer to it using a relative path. Sidebars can only use 'local' JS, they cannot load scripts from the internet.

cross rider extension to fetch new posts from feed using google feeds api

I am trying to create an extension to display all the latest posts fetched from my feed using google feeds api. To implement this, I have added this code in background.js:
appAPI.ready(function() {
// Global variable to hold the toggle state of the button
var buttonState = true;
// Sets the initial browser icon
appAPI.browserAction.setResourceIcon('images/icon.png');
// Sets the tooltip for the button
appAPI.browserAction.setTitle('My Postreader Extension');
appAPI.browserAction.setPopup({
resourcePath:'html/popup.html',
height: 300,
width: 300
});});
and in popup.html,
<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript">
function crossriderMain($) {eval(appAPI.resources.get('script.js')); }</script>
</head>
<body><div id="feed"></div></body></html>
The script.js file is-
google.load("feeds", "1");
function initialize() {
var feed = new google.feeds.Feed("http://www.xxxxx.com/feed/");
feed.setNumEntries(10);
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("feed");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
var link = document.createElement('a');
link.setAttribute('href', entry.link);
link.setAttribute('name', 'myanchor');
div.appendChild(document.createTextNode(entry.title));
div.appendChild(document.createElement('br'));
div.appendChild(link);
div.appendChild(document.createElement('br'));
container.appendChild(div);
}
}
});
}
google.setOnLoadCallback(initialize);
But I am unable to get desired result.The popup doesn't display anything.It just remain blank.
Since you are using a resource file for the popup's content, it's best to load the remote script from the crossriderMain function, as follows:
<!DOCTYPE html>
<html>
<head>
<!-- This meta tag is relevant only for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript">
function crossriderMain($) {
appAPI.db.async.get('style-css', function(rules) {
$('<style type="text/css">').text(rules).appendTo('head');
});
appAPI.request.get({
url: 'http://www.google.com/jsapi',
onSuccess: function(code) {
$.globalEval(code);
appAPI.db.async.get('script-js', function(code) {
// runs in the context of the extension
$.globalEval(code.replace('CONTEXT','EXTN'));
// Alternatively, run in context of page DOM
$('<script type="text/javascript">').html(code.replace('CONTEXT','PAGE DOM')).appendTo('head');
});
}
});
}
</script>
</head>
<body>
<h1>Hello World</h1>
<div id="feed"></div>
</body>
</html>
[Disclaimer: I am a Crossrider employee]

ExtJS disableCache doesn´t working

I use ExtJS 4 and a RESTProxy. Every time I send a request (PUT or GET) I get the cache included in my request:
http://localhost:9000/todos?_dc=1355520254945
Here is my Store definition:
Ext.define('MyStore'), {
extend: 'Ext.data.Store',
model: 'MyModel',
proxy: {
type: 'rest',
url: '/todos',
disableCaching: false
}
});
I used also disableCaching: false, but it doesn´t work.
try this:
noCache: false
because disableCaching field doesn´t exists.
You can turn off caching globally like this
<script src="ext-all.js" type="text/javascript"></script>
<script type="text/javascript">
Ext.data.Connection.disableCaching = false; // for file uploads
Ext.data.proxy.Server.prototype.noCache = false; // for all stores loads
Ext.Ajax.disableCaching = false; // for all Ext.Ajax.request()
</script>
<script type="text/javascript" src="app.js"></script>