I am setting up a simple crud app. However, I am not sure what is going on with ui-router. I read that you should use html tags so I tried this as well. Here is my code.
app.js
app.get('/templates/:templateid',indexController.getTemplate);
index controller
var indexController = {
index: function(req, res) {
res.render('index');
},
getTemplate:function(res,req){
res.render('templates/' + req.params.templateid);
}
};
module.exports = indexController;
Here is my main.js
var app = angular.module('myApp',['ui.router']);
app.config(function($stateProvider,$urlProvider){
$stateProvider('home',{
url:'/home',
templateUrl:'templates/home.jade',
controller: 'HomeController'
})
})
app.controller('HomeController',function($scope){
console.log('home is here');
})
My index.jade shows as so
extends layout
block content
h1 Lets Get Cruddy
<div ui-view></div>
I have called ng-app in my layout. This should be fairly simple right?
The router only interprets html
you should point the template url to the compiled html file so
templateUrl:'templates/home.html
that's if templates/home.jade compiles to templates/home.html
As Dr Manhattan said, AngularJS does not render a Jade file, however, if you have a server side language such as NodeJS, you can change view engine to Jade.
For simplicity sake, I would also recommend creating a NodeJS application with Express so you can create a route that will render the view and take advantage of the simplicity of Jade.
Add the following to your App.js file in your NodeJS application:
app.set('view engine', 'jade');
In your NodeJS route, you will add something like this:
var router = express.Router();
// index.js
// http://www.yourdomain.com/ is the path to this route
router.get('/', function(req, res, next) {
res.render('home', {
title: 'Express'
});
});
In your main.js file, you will change the templateURL to the following:
templateUrl:'/',
Jade will render the template to HTML and make it readable for AngularJS.
Related
I have a js file located in assets folder (not View). can i pass a varible from a controller?
In view file:
The Js is called like this
<canvas id="chart1" class="chart-canvas"></canvas>
</div>
It is not possible (in my point of view) to put a variable to external JS file. You can use data-... attributes and get values from html elements.
For example you can pass your PHP variable as a json encoded string variable in your controller.
$data['chart_info'] = json_encode($chart_info);
return view('your_view', $data);
Then put it in data-info like this.
<canvas id="chart1" class="chart-canvas" data-info="{{ $chart_info }}"></canvas>
And finally in JS, you can get the variable and decode (parse) it as following.
let canvas = document.getElementById('chart1');
let info = JSON.parse(canvas.dataset.id);
console.log(info);
You can put that part of the Javascript in the view and send the variable to the same view. For example, add a section in view:
#section('footer')
<script type="text/javascript">
</script>
#endsection
Do not forget that you should add #yield('footer') to the end of your layout view.
I don't like to mix javascript and PHP/Blade, it might be hard to read the code in the future... You could use a different approach, loading the chart with a async ajax request.
You will have to create a end-point that returns the data you need for your chart:
Your router:
Route::get('/chart/get-data', [ ControllerName::class, 'getChartData' ]);
Your controller method:
public function getChartData() {
$chartData = [];
// Your logic goes here
return $chardData;
}
In your javascript (using jquery) file there will be something like that:
function loadChartData() {
$.ajax({
'url': '/chart/get-data',
'method': 'GET'
})
.done((data) => {
// Load your chart here!!!
})
.fail(() => {
console.log("Could not load chart data");
});
}
Hope I helped ;)
I am having difficulty knowing the flow of react-router by (https://github.com/rackt/react-router).
If i have 2 files: routes.js, app.js(entry component) as below:
var Router = require('react-router');
var Route = Router.Route;
var routes = (
<Route handler={App}>
<Route path="/" handler={home}/>
</Route>
);
module.exports = routes;
app.js
var React = require('react');
var Router = require('../routes.js');
var RouteHandler = Router.RouteHandler;
var App= React.createClass({
render: function(){
return (
<RouteHandler/>
)
}
});
module.exports = App;
How does the app component gets called? As of traditional way i use following code to render "app" component in app.js.
React.render(
<App />, document.getElementById('main')
);
Now what i dont understand is what is the following code doing. Is it replacement of traditional way of rendering, i need to use following code to listen to url and render app.js but not the above code?
Router.run(routes, Router.HashLocation, (Root) => {
React.render(<Root/>, document.body);
});
What if i am using another js file "main.js" to render "app.js" and now i want to use app.js to handle all the route how do i do it. Mean to say i want to render what ever the route is passed in app.js.
My code in main.js is below:
React.render(
<APP />, document.getElementById('main')
);
First off, you need to update your App.js file to grab the correct react-router module. You're assigning the export of your routes.js file to Router, but it should be react-router. Node will actually cache the result of the module and reuse it for every other reference to it.
Your approach would work ok -- typically you see something like a Main.js file to handle the routing, and the App.js is more of the wrapper for your component(s).
So I would make a Main.js file like so..
// Main.js
var React = require('react');
var Router = require('react-router');
var routes = require('../routes.js');
var RouteHandler = Router.RouteHandler;
Router.run(routes, function(Handler, state) {
React.render(<Handler />, document.body);
});
Then, just make your App.js mount the RouteHandler and handle any other parent state. When you navigate to the route, it will match it in the Router.run function and then all routes in the 'family' of the matched route will be rendered.
I have recently migrated from a codeigniter framework, to a nodejs with an express framework. Our codeigniter site had a lot of JS as it was, and we made a lot of AJAX calls because it is a single page app. We are messing around with node and express now, and I cannot get a simple AJAX call to function. It could be a lack of understanding of node, it could be something else. We are using openshift to host. We are using hogan-express as a template.
server.js
var express = require('express');
var fs = require('fs');
var http = require('http');
var path = require('path');
var SampleApp = function() {
var self = this;
self.initializeServer = function() {
self.app = module.exports = express();
self.app.configure(function() {
self.app.set('views', __dirname + '/views');
self.app.set('view engine', 'html');
self.app.engine('html', require('hogan-express'));
//self.app.set('layout', 'layout') # use layout.html as the default layout
self.app.use(express.favicon());
self.app.use(express.logger('dev'));
self.app.use(express.bodyParser());
self.app.use(express.methodOverride());
self.app.use(express.session());
self.app.use(self.app.router);
self.app.use(require('stylus').middleware(__dirname + '/public'));
self.app.use(express.static(path.join(__dirname, 'public')));
});
require('./routes');
}
There is more code in this file, I am only including the relevant code (I think).
Ajax.html
<div id="button">
<button id="testbutton">Push Me!</button>
</div>
<div id="populate">{{title}}</div>
<div id="null">{{>part}}</div>
<script type='text/javascript'>
$(function(){
$('#testbutton').click(function (){
$.ajax({
url:'/test',
type: 'POST',
success: function(result){
alert('success!');
},
error: function(){
alert("well this is embarassing... if the problem persists please let us know at facebook.com/stembuds");
}
});
});
});
</script>
index.js
app = require('../server');
app.get('/', function(req, res){
res.render('ajax');
});
app.post('/test', function(req, res){
console.log('get');
res.locals = {title: 'Horray'};
res.render('ajax', {partials:{part:'part'}});
});
part.html
<p> pass me in!!</p>
So basically what I am trying to do is when the button is clicked I want the ajax call to show a partial view. The way we are going to structure the site is to have one single page, and have the ajax calls render different views based on the buttons that the user clicks. So here is the interesting part: I get the success alert from the ajax call, but the {{title}} and the {{>part}} never show up. However, when I go to the console and click 'network', and then click 'test' (the url to my ajax call), the response shows the divs populated with "Horray" and "pass me in!!". Sorry for the length, and thank you for any information you can provide us.
If you are calling your resources with ajax (as you are doing) then you get the response to your ajax function. After successful call you need to render the view in your client side JS code.
What I mean is that your code works as expected, but your backend cannot update your browsers view. You need to do it client side or load the whole page again from the server.
Your success hander could be something like this:
success: function(result){
renderTheResults(result);
},
You can just send the JSON. You need to send the json via send not render. Because render is supposed to deliver the full HTML page. May be .ejs file.
For example:
res.send({partials:{part:'part'}});
res.send should be used to pass json to your page. And on your page you have to use the JSON to populate the HTML dynamically.
I created a project for easy content sharing. You can look at my project here:
SharingProject
You can use user#example.com with 123456 as password to test the site as verified user. Of course the site has some bugs yet...
I used the meteor user package and the backbone package to navigate through the pages.
On localhost, there is no problem. For testing I uploaded the project to the meteor server. Now while I am logged in and navigating through the pages, every time I navigate to a new page the app 'checks' the user on client side because of the url change. This is annoying...
Of course I could navigate through the pages only calling Session.set('page_id', ..) but my goal is to be able to send people an url to a specific page on the server.
The code is similar to the one in the todos example from the meteor page:
Meteor.subscribe('pages', function () {
if (!Session.get('page_id')) {
var page = Pages.findOne({}, {sort: {owner: -1}});
if (page)
Router.setPage(page._id);
}
});
...
var PagesRouter = Backbone.Router.extend({
routes: {
":page_id": "main"
},
main: function (page_id) {
Session.set("page_id", page_id);
},
setPage: function (page_id) {
this.navigate(page_id, true);
}
});
Router = new PagesRouter;
Meteor.startup(function () {
Backbone.history.start({pushState: true});
});
Why I am asking here: I searched the web and can't find anyone with the same problem. So either nobody tried this before or there is a simple solution for this?
Edit: How I call the pages
<template name="pages">
{{#each pages}}
<p>{{title}}
{{#if isauthor}}
<a class="delPage" href="javascript:delPage('{{_id}}')">delete</a>
{{/if}}
</p>
{{/each}}
</template>
I don't know how you are rendering the page links but a link like this :
http://pagesharingproject.meteor.com/a1fbacba-0ddf-4077-a653-294b428bbfb8
should read like:
http://pagesharingproject.meteor.com/#a1fbacba-0ddf-4077-a653-294b428bbfb8
Ok I solved the problem, changing (true)
Meteor.startup(function () {
Backbone.history.start({pushState: true});
});
to (false)
Meteor.startup(function () {
Backbone.history.start({pushState: false});
});
and of course adding an anchor like Mubix suggested. Thanks for the hint!
It is up to date on the site mentioned above.
I spend some time today on the backbone documentation, but I can't imagine why this is working? Especially I am wondering why
{hashChange: false}
doesn't work here?
So I have my first MVC2 site that I'm working on and naturally I'd like to throw some AJAX in there. The problem is, is that I don't know how to get the URL for the action when passing in a URL parameter. Let me explain. The examples I've seen so far show the developer passing in strings like '/MyController/MyAction'. That's great, except if your controllers are not in the root directory of your website (as is the case in my situation). I could always use relative URLs like 'MyAction' except if the URL contains parameters that doesn't work either. Consider http://example.com/myroot/MyController/MyAction vs http://example.com/myroot/MyController/MyAction/PageNumber/SomeOtherValue. Now the relative URL will be incorrect.
In the ASPX code, this is easy. I just write in <%= Url.Action("MyAction") %>. But how do I do this in my javascript file?
This is part of the long-standing issue that including server-sided code in JavaScript files is not really possible :(. (Without serious hacks, that is.)
The best solution is to include the action URL inside your HTML file somewhere, then get that value from JavaScript. My suggestion would be something like this:
<!-- in your view file -->
<form id="MyForm" action="<%: Url.Action("MyAction") %>"> ... </form>
<!-- or -->
<a id="MyLink" href="<%: Url.Action("MyAction") %>"> ... </a>
combined with
// In your .js file
$("#MyForm").submit(function ()
{
$.post($(this).attr("action"), data, function (result) { /* ... */ });
return false;
});
// or
$("#MyLink").click(function ()
{
$.getJSON($(this).attr("href"), data, function (result) { /* ... */ });
return false;
});
This feels semantically clear to me, and in some cases even creates degradable fallback behavior for when JavaScript is turned off.
You can't do this in your JavaScript file directly, however you can pass these dynamic values into your script by way of a script initializer. Consider the following example:
External Js file
ShoppingCart = function() {
this.settings = {
AddProductToCartUrl: '',
RemoveFromCartUrl: '',
EmptyCartUrl: '',
UpdateCartUrl: ''
};
};
ShoppingCart.prototype.init = function(settings) {
this.settings = jQuery.extend(this.settings, settings || {});
};
HTML/View
<script type="text/javascript">
var cart = new ShoppingCart();
cart.init({ AddProductToCartUrl: '<%=Url.Action("MyAction")%>' });
alert(cart.settings.AddProductToCartUrl);
</script>
Simple: tell your javascript what the correct URL is.
Tactically, you can get there alot of ways, but they basically break down into two techniques:
Have a server-side generated javascript "configuration" so you can do something like var url = siteConfiguration.SITEROOT + 'products/pink-bunny-slippers' Note this file can be a normal MVC view, the only trick is you have to tell the controller to send a text/javascript header rather than text/html.
Basically, dependency inject it into your script. IE function wireUpAjaxLinksToService(linkIdentifier, serviceEndpoint) where you call using something like wireUpAjaxLinks('a.ajax', '<%= Url.Action("MyService", "Services") %>')