Absolute beginner here. I want to load data into models as soon as the page loads.
Before anything else is executed. At the moment I have this code.
// Model code
var Portfolio = Spine.Model.sub({});
Portfolio.configure("Portfolio")
Portfolio.extend({
populate: function(values){
for(var i in values[0]){
// add attributes to Model
this.attributes.push(i);
}
for(var j = 0; j < values.length; j++ ){
var tmpInst = this.create(values[j]);
tmpInst.save();
}
}
});
// app controller code
$(function(){
var App =Spine.Controller.sub({
init: function(){
jQuery.getJSON("../xml/data.json",
function(result){
Portfolio.populate(result['content']);
}
).complete(function(result) {
// do other stuff
});
}
})
var app = new App();
});
So when the page has finished loading the controller init function is called, which retrieves the json data and passes it to the Model which parses it and creates the individual instances.
Am I doing this wrong? I have seen Fetch function in the documentation but with no example of how it works.
You might want to use Spine's framework to do this:
Instead of firing your own jQuery.getJSON(), include Spine.Ajax in your Model.
Portfolio.extend(Spine.Model.Ajax);
Set the Spine.Model.host to your server
Add url attribute/method to your Portfolio object to something like 'xml/data.json'
Call Portfolio.fetch()
Override Portfolio.fetch() function to extract just the node of array data or whatever initialization you had in mind just like the configure. If I am not mistaken, fetch() will load the objects and set all the attributes provided in the JSON even if they are not configured in Model #configure call
Related
I am working on a reporting related project, where I need to build lot of reports rendered using KO. All data pulled using AJAX and the model is updated. Currently I am writing tons of js functions to map the models. Something like:
function modelx(child) {
var self = this;
self.Name = ko.observable(child.Name);
self.Relation = ko.observable(child.Relation);
// hundred other properties
};
function modely(child) {
var self = this;
self.Age = ko.observable(child.Age);
self.Relation = ko.observable(child.Relation);
// hundred other properties
};
and after AJAX call, I am filling the observable arrays
for (var i = 0; i < jsn.length; i++)
{
VM.modelxlist().push(new modelx(jsn[i]));
}
for (var i = 0; i < jsn1.length; i++)
{
VM.modelylist().push(new modely(jsn1[i]));
}
Is there any way to avoid the definition of modelx, modely,... such that the model is automatically built without loosing the benefits of this approach while using in HTML? Of course there could be a corner case where I may not get a specific property from server, which I should check on the server side.
Also, at times I may need to add additional computed observables (just to be more flexible)
Why don't you use knockout mapping plugin:
http://knockoutjs.com/documentation/plugins-mapping.html
You would then have something like:
var modelxInstance= ko.mapping.fromJS(child);
There are a few mapping plugins for knockout, the one i like the most is actually this one:
https://github.com/LucasLorentz/knockout.mapper
And the reason is that it is more configurable and it is faster.
I think this is what you want..
With ko.mapping.fromJS method u can automatically observe all the properties from your object..
Take some time to read about that..
i have a poll application with 2 views, list view and single item view. these are the init functions in the angular client controller
// Poll List
$scope.pollList = function(){
$scope.votes = Votes.query({
userId:Authentication.user._id
});
$scope.polls = Polls.query();
};
// View Poll
$scope.findOne = function(){
$scope.votes = Votes.query({
userId:Authentication.user._id
});
$scope.poll = Polls.get({
pollId: $stateParams.pollId
});
$scope.categories = Categories.query();
$scope.languages = Languages.query();
$scope.pollItem($scope.poll);
};
// Poll Item
$scope.pollItem = function(poll){
$scope.pollVoted(poll);
$scope.countPollVotes(poll);
for (var i = 0; i < poll.poll_options.length; i++){
$scope.optionItem(poll,poll.poll_options[i]);
};
};
both the list view and the single view initiate a pollItem function in each poll object. in the list view everything works good - each poll object passes the pollItem function without an error. but in the single poll view im recieveing errors, namely, that the diffrent attributes of the poll (i.e user, comments, poll_options) are returning undefined! allthough when i console.log the poll object i can see them all there. please help! im aware to the fact that it sounds a bit vague but im not sure which other details to provide.. im stuck a couple of days on this problem and no answer to be found.
I have ddl(drop down list) which populates from database after change event of another ddl but I want to change the value of this ddl after it populated from database.
Example:
// This work very well
$("#ddlGroups").on('change',function(){
// Load data from database and populate ddlUsers
// response is loaded from database with $.ajax
// Query Example: SELECT User_ID, Username FROM tblUsers WHERE Group_ID = [Group_ID] (Just for undrestanding the question)
var Records = response.d;
$("#ddlUsers").empty();
$.each(Records, function(){
var _Key = this.User_ID;
_Value = this.Username;
$("#ddlUsers").append($("<option />").val(_Key).text(_Value));
});
});
// When button clicked then trigger ddlGroups change event and assign select option from ddlUsers
var _UserID = User_ID_From_Database; // Loaded from Database when button clicked
$("#ddlGroups").trigger('change'); // Users are loaded from database based on group ID
$("#ddlUsers").val(_UserID); // But this dosn't change
How do I check if ddlUsers is loaded or not, I tried while loop but it never stops.
With jquery there are two main ways (really the same underlying) to connect a ajax response from the database to a event or UI result. The first is promises and the second is a callback. Both these have 1 million examples and jquery documentation is quite robust.
In your case rather than "trigger", you callback calls the right function. The below is just junk code to show.
No: $("#ddlGroups").tigger('change');
Yes:
//Your code
$("#ddlGroups").on('change', updateDDL);
//I have just externalized this function to a scope/place where both the ajax and on change line of code can reference it.
function updateDDL(){
var Records = response.d;
$("#ddlUsers").empty();
$.each(Records, function(){
var _Key = this.User_ID;
_Value = this.Username;
$("#ddlUsers").append($("<option />").val(_Key).text(_Value));
}
};
$.ajax(...., function (data) {
// Update ddl, the existing function you have.
// You should already have something like this.
updateDDL(); //Like this
});
BTW: You could pass the data into the updateDDL directly use $(this) in the updateDDL to improve it etc but that is not key to your question/issue. It seems that you are new to jquery and some of the Javascript features it uses. Take a little time to learn about them and you will be WELL rewarded. I would start by reading examples around ajax/jquery and watch how then update the DOM.
In my bb router I get some JSON data
$.ajax({
url: "js/projects.json",
success: function(projects) {
database.projects = projects;
var variables = {};
var niz = new Array();
var param = "Client"
$.each(projects, function()
{
if (!variables[this[param]])
variables[this[param]] = [];
variables[this[param]].push(this);
});
for(var d in variables) {
niz.push(d);
var number_of_clients = niz.length;
}
console.log(number_of_clients);
Backbone.history.start();
}
});
Now I wanna access this "projects" from one of my Views and to some stuff with that data , I know I can do the same thing again like here , but its duplicating code , is there any way to get this data in View ? I tried a few things but with no success , I allways get the undefined
You can attach your data to the window (window.projects = projects), then you can access it from everywhere. But I recomend you to use the ajax tools from Backbone, it's much easier and less messy.
Honestly, your question seems very suspicious design-wise. :)
Ajax calls should be made in models using the fetch function, not in a router, and not using jquery directly.
So I would advise you to redesign your app unless you have a strong reason not to do so.
Scenario:
The MVC web page gets JSON object with lots of data. Upon click of button (there are quiet a number of buttons) I would like to reuse this JSON object and select required JSON Properties (without making a request to server).
It's not HTML5 so can't use browser local storage. At the moment I'm storing the JSON object on GLOBAL variable and reusing it.
Are there any elegant options available to store and re-use returned JSON object on client side?
Just cache the data. There is no need to store the JSON in a global variable, I'm sure you'll find a place in your MVC application to scope a local variable. You will have implemented a getter function for the data with a callback. With caching, it'll look like this:
var getData = (function(){
var cache;
var loading = false;
var callbacks = [];
return function(callback) {
if (typeof cache != "undefined")
callback(cache);
else {
callbacks.push(callback);
if (!loading) {
loading = true;
doSingleHeavyAjaxCall(options, function success(data) {
cache = data;
for (var cb; cb = callbacks.shift();)
cb(cache);
});
}
}
};
})();
Then use getData(function callback(data){...}) as often as you want, and it will only trigger one ajax request.
Another option to Jakubs answer is creating a global variable that you can update and retrieve as you like on the page.
Global variables get attached to the window object, so just write this in your <head> section.
<script type="text/javascript">
window.jsonData = {};
</script>
Then wherever you're retrieving your data just update that object.
<script type="text/javascript">
$.ajax(..., function(data) {
window.jsonData = data;
});
</script>
Then you can use it wherever you like in your code on that page.
<script type="text/javascript">
console.dir(jsonData);
</script>
You can store the object in data- attribute of some element - preferably container for the part of your page that represents your data (table, grid):
var json = {};
$('#mygrid').data('mydata', json);
You can retrieve it later
var json = $('#mygrid').data('mydata')
jQuery data() method documentation: http://api.jquery.com/data/