UI5 Component Concept issue - components

I'm trying to use the component concept for UI5 and have just built the below:
Index.html snippet:
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-resourceroots='{
"sap.ui.ui5test.myapp": "./"
}'>
</script>
<!-- only load the mobile lib "sap.m" and the "sap_bluecrystal" theme -->
<script>
new sap.m.Shell({
app : new sap.ui.core.ComponentContainer({
name : "sap.ui.ui5test.myapp"
})
}).placeAt("content");
</script>
Component.js snippet:
jQuery.sap.declare("sap.ui.ui5test.myapp.Component");
sap.ui.core.UIComponent.extend("sap.ui.ui5test.myapp.Component", {
createContent : function() {
var oView = new sap.ui.core.mvc.View({
id : "testview",
name : "sap.ui.ui5test.myapp.views.FirstView",
type : "JS",
viewData : {component : this}
});
var jsonModel = new sap.ui.model.json.JSONModel();
jsonModel.loadData('http://api.openweathermap.org/data/2.5/weather?q=Auckland');
//jsonModel.loadData('http://api.openweathermap.org/data/2.5/group?id=524901,703448,2643743&units=metric');
sap.ui.getCore().setModel(jsonModel);
oView.setModel(jsonModel);
}
});
In the above snippet for component.js, if I return the view as return oView; it is giving me an error saying "Uncaught TypeError: undefined is not a function". It goes away as soon as I remove the return statement.
If I dont return the view will it navigate to the view I instantiated and loaded above? As I see in the chrome developer tools, I do not seem to find the js file for FirstView to open it as I think it is not getting loaded.
Please suggest how to correct this and how to navigate further.
Awaiting your prompt responses eagerly.
Cheers,
AW

I checked your FirstView.js. Please do the following in your return statement:
return this.app;
As there is no local variable called app, if you write return app, then app is undefined.
Please use sap.ui.view in your createContent method:
var oView = new sap.ui.view({
id : "testview",
viewName : "sap.ui.ui5test.myapp.views.FirstView",
type : "JS",
viewData : {component : this}
});

Related

ng-view doesn't work correctly

I want to implement ngRoute in my angularjs project. But <ng-view></ng-view> doesn't show anything. I read all other posts about this problem, but my problem is not resolved.
I define $routeProvider in app.js file as follows:
'use strict'
angular.module('confusionApp', ['ngRoute'])
.config(['$routeProvider',function($routeProvider) {
$routeProvider
.when('/contactus', { // route for the contactus page
templateUrl : 'contactus.html', controller : 'ContactController'
})
.when('/menu', { // route for the menu pag
templateUrl : 'menu.html', controller : 'MenuController'
})
.when('/menu/:id', { // route for the dish details pag
templateUrl : 'dishdetail.html', controller : 'DishDetailController'
})
.otherwise('/contactus');
}]);
My controllers.js file includes the defenition of all my controllers:
angular.module('confusionApp')
.controller('MenuController', ['$scope','menuFactory',function($scope,menuFactory){
$scope.dishes = menuFactory.getDishes();
//other codes which deleted for simplicity
}])
.controller('dishDetailController',['$scope','$routeParams',
'menuFactory', function($scope,$routeParams,menuFactory){
var dish = menuFactory.getDish(parseInt($routeParams.id,10));
this.dish = dish;
//other codes which deleted for simplicity
}])
.controller('contactController',['$scope',function($scope){
//some code here
}])
.controller('feedbackController',['$scope',function($scope){
//some code here
}]);
And I defined factory in services.js file as follows:
angular.module('confusionApp')
.factory('menuFactory',function(){
var menufac = {};
var dishes=[{... some data ...}];
menufac.getDishes = function(){
return dishes;
};
menufac.getDish = function(index){
return dishes[index];
};
return menufac;
});
In my index.html page <ng-view></ng-view> doesn't show anything.for example when I click on menu tab, url become like this and menu data didn't reload:
http://localhost/conFusion/#!/contactus#%2Fmenu
my default page is contactus.
Also I define scripts in index.html as follows and all the paths are true.
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/angular-route/angular-route.min.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers.js"></script>
<script src="scripts/services.js"></script>

Browserify with nodejs is not working

I am creating a sample application to learn how to use nodejs for client side. I have installed : node, npm with browserify before running this exercise;
Directory Structure
lesseon1
- index.html
- application.js
- js
- data.js
- listdata.js
index.html
<!DOCTYPE html>
<html>
<head>
<title>Node Lesson 1</title>
<script type="text/javascript" src="application.js"></script>
</head>
<body>
<div id="names"></div>
<script type="text/javascript">
var ol = document.createElement("ol");
ol.innerHTML = window.list;
document.getElementById("names").appendChild(ol);
</script>
</body>
</html>
listdata.js
var jsonData = require("./data.js");
for(item in jsonData){
console.log(jsonData[item].name);
window.list += "<li>" + jsonData[item].name + "</li>";
}
console.log(window.list);
data.js
var json = [{
"name" : "Rohit"
},{
"name" : "Amit"
},{
"name" : "Arti"
}];
And application.js is being generated using browerify
~/node_modules/.bin/browserify -e js/listdata.js -o application.js
Problem :
It is printing undefined in browser and browser console too. However if I copy paste js code in index.html, everything works fine.
In listdata.js, there are 2 console.log() statements. But it is executing only last one.
Am I missing something? or doing something in wrong way.
You did not export from data.js.
var json = [{
"name" : "Rohit"
},{
"name" : "Amit"
},{
"name" : "Arti"
}];
module.exports = json;
Or you can change to data.json and just type in valid json without var or exports and use it in listdata.js as var jsonData = require("./data.json");
Each required file, browserify wraps into function with function (require, module, exports) signature. That is reason why you might not have some variables globally. If you want so, use global. or window..

Unable to load Meteor template, set context and bind events

I am trying to render and append a template (ticket_edit) to the body. I need to set a context to the newly appended template, and the events of ticket_edit should be bound to that template.
The code:
Template.ticket.events = {
'click a.edit' : function (event) {
//when the edit button has been clicked, load template 'ticket_edit'
//with the current context. Please see situation 1 and 2.
}
}
Template.ticket_edit.events = {
'click a.save' : function (event) {
//this won't do anything when i have supplied a context!
}
}
So the problem is:
-I can set the context, but then the events are not bound to the newly added template.
-If I don't set the context the events are bound properly.
But i need both the events and the context.
Situation 1:
'click a.edit' : function (event) {
//applying a context to the template will result in events not being bound.
$('body').append(Meteor.render(Template.ticket_edit(this)));
}
Sitation 2:
'click a.edit' : function (event) {
//this way, the events will execute properly and i can save my ticket.
//However, no context is supplied!
$('body').append(Meteor.render(Template.ticket_edit));
}
Does anybody have a good method for doing this? I'm fairly new to Meteor, so maybe you have a better method of dynamically loading templates.
Don't use jQuery for this, just do it directly with the template and a #with block. Something like this:
<body>
{{> tickets}}
</body>
<template name="tickets">
{{#each tickets}}
{{> ticket}}
{{/each}}
{{#with currentTicket}}
{{> editTicket}}
{{/with}}
</template>
Template.tickets.tickets = function() {
return Tickets.find();
};
Template.tickets.currentTicket = function () {
return Tickets.findOne({ _id: Session.get( "currentTicket" ) });
};
Template.ticket.events({
'click a.edit' : function () {
Session.set( "currentTicket", this._id );
}
});
Because we're using a #with block, the editTicket template won't get rendered until you click the edit button (setting the "currentTicket" in the Session).
It's also possible to just do this (no #with block):
{{> editTicket currentTicket}}
But that causes editTicket to always be rendered, just without any context until the Session var gets set.
Note that because we're using Session, the user won't be interrupted by reloads/hot code pushes.

PJax not working with MVC project

I've followed the samples. I added a _PjaxLayout:
<title>#ViewBag.Title</title>
#RenderBody()
Modified my _Layout:
<div id="shell">
#RenderBody()
</div>
<script type="text/javascript">
$(function () {
// pjax
$.pjax.defaults.timeout = 5000;
$('a').pjax('#shell');
})
</script>
Updated ViewStart:
#{
if (Request.Headers["X-PJAX"] != null) {
Layout = "~/Views/Shared/_PjaxLayout.cshtml";
} else {
Layout = "~/Views/Shared/_Layout.cshtml";
}
}
Yet every time I click on an 'a' tag, the pjax code doesn't get called. It's as if the selector isn't working when I set up pjax. What am I doing wrong?
UPDATE:
If I do this:
$('document').ready(function () {
$('a').pjax({
container: '#shell',
timeout: 5000
});
});
I see the pjax code getting hit and the Request headers get updated, and the new content loads on the page, but the styling and layout get really messed up and duplicated...
UPDATE:
Inspecting the DOM after this craziness happens reveals that the new page content is getting loaded directly into the anchor that I click, instead of into the element with id #shell. WTF?
You are using a legacy syntax, the new pjax uses the following:
$(document).pjax('a', '#shell', { fragment: '#shell' });
Also I am not familiar with the language you use, but in order to make pjax happen there has to be an HTML element with the id shell in your ViewStart.
As I am not sure about the syntax in that language, try something similar to this for testing:
#{
if (Request.Headers["X-PJAX"] != null) {
echo "<ul id="shell"> pjaaxxx </ul>"; // Would work in php, update syntax
} else {
Layout = "~/Views/Shared/_Layout.cshtml";
}
}
I am not seeing that syntax as valid in the PJax documentation.
Are you sure you didn't mean $(document).pjax('a',{});?
$.pjax immediately executes from what I can tell.

Handlebars.js misses JSON data

I've got template file loaded by Require.js via this:
main-app.js
define([
'backboneLoader',
'handlebars',
'text!templates/main.html',
'text!appdata.json'
],
function(
Backbone,
Handlebars,
MainTemplate,
AppData
) {
"use strict";
return Backbone.View.extend({
initialize : function() {
this.render();
},
render : function() {
var template = Handlebars.compile(MainTemplate);
var output = template(AppData);
this.$el.append(output);
console.log("appData:\n" + AppData);
console.log("MainTemplate:\n" + MainTemplate);
console.log("Output:\n" + output);
//smth extra
return this;
}
});
}
);
MainTemplate (main.html)
<ul>
<li><b>Version:</b> {{version}}</li>
<li><b>Author:</b> {{author}}</li>
</ul>
AppData (appdata.json)
{version: "0.0.1", author: "John Doe"}
And output:
<ul>
<li><b>Version:</b></li>
<li><b>Author:</b></li>
</ul>
While expected output:
<ul>
<li><b>Version:</b> 0.0.1</li>
<li><b>Author:</b> John Doe</li>
</ul>
Any ideas what am I doing wrong? Thank you!
UPD:
Problem solved. Here is updated main-app.js:
define([
'backboneLoader',
'handlebars',
'text!templates/main.html!strip',
'text!appdata.json'
],
function(
Backbone,
Handlebars,
mainTemplate,
appData
) {
"use strict";
return Backbone.View.extend({
initialize : function() {
this.render();
},
render : function() {
var template = Handlebars.compile(mainTemplate);
var output = template(eval("(" + appData + ")")); //Object is expected by template(), not JSON.
this.$el.append(output);
console.log("appData:\n" + appData);
console.log("template:\n" + mainTemplate);
console.log("Output:\n" + output);
//smth extra
return this;
}
});
}
);
The problem is AppData is a string of JSON, not an actual Object. Simply change from:
var output = template(AppData);
to
var output = template(JSON.parse(AppData));
You may need to include json2.js to add JSON support for older browsers (<=IE7).
Here is a jsFiddle repro of your template function, the template transformations seems working, the problem is probably located in the text! function in require.js code, try to debug the text! function.
Try also to add the !strip function when loading the template: 'text!templates/main.html!strip',
The documentation suggests it :For HTML/XML/SVG files, there is another option. You can pass !strip, which strips XML declarations so that external SVG and XML documents can be added to a document without worry.

Resources