How to rebind variable assignments - javascript

I am currently attempting to build my own JS framework as a way to learn. I have created a method for making an new model like so:
var myModel = new $n.model.make({
data: {
id: _contentID,
name: $('#frm_content_name').val()
},
route: '/my/path',
callback: function(){}
});
The make() function is simple:
$n.model.make = function(obj){
var self = this;
self.data = obj.data;
self.route = obj.route;
self.callback = obj.callback;
}
As you can see, the name parameter is assigned to a form input field's value. If I change this input field value on the UI, the name parameter is still assigned to the original value of the input field so if I try to save the data to the DB, nothing has changed.
Once I have established my model, what is a good way to "rebind" the data parameters to their assigned form fields to get the latest information?

As mentioned in a comment you could do this:
data: {
id: _contentID,
name: function() {
return $('#frm_content_name').val();
}
},
Calling data.name() would always fetch the latest information. Another way is this:
data {
id: _contentID,
name: $('#frm_content_name')
},
Now you would need to call data.name.val(); personally I don't really like this because of the missing encapsulation.

I found the answer I was looking for - two-way data binding. Here is the tutorial I used to solve my issue: http://www.lucaongaro.eu/blog/2012/12/02/easy-two-way-data-binding-in-javascript/

Related

JavaScript knockoutjs, set nested object value doesn't update Html?

I'm using knockout 3.3.0. Assume I have a model as the following:
As you can see There are two nested objects, DeviceStatistics and Product.
At first they are OK and work fine and update HTML.
I assign the new values to these objects as the following:
window.KoEntityModel.EntityModel.DeviceStatistics = ko.mapping.fromJS(newJsonModel);
It's OK without any problems, but knockout doesn't update(change) HTML
Whereas, chrome console shows window.KoEntityModel.EntityModel.DeviceStatistics is observable:
How can I fix it?
well to convert object into function you need to do something like below
viewModel:
var fromserver = {
'device': {
'one': 'onevalue'
},
'product': {
'prod': 'prodone'
},
'name': 'supercool'
};
var ViewModel = function() {
var self = this;
self.device = ko.observable();
self.prod = ko.observable();
ko.mapping.fromJS(fromserver, {}, self); //this converts object into function & keeps the other prop's coming from server intact .
};
var vm = new ViewModel();
ko.applyBindings(vm);
working sample fiddle here shows the modified data .
I found the solution,
We have to update a knockoutJs view model with the following code:
ko.mapping.fromJS(newDataInJson, {}, knocoutJsViewModel);

how can I call the (ko.observableArray) from (init) JSON function?

Well the title is confusing so I'll give you my code to understand my problem
in knockout tutorials they use functions instead of JSON I mean like this:
data = [
{
id: 1,
name: 'somehing'
},{
id: 2,
name: 'somehing else'
},
]
here is my problem
var ViewModel = function () {
var self = this;
self.dataList = ko.observableArray(data);
console.log(ViewModel.dataList);
};
while on other websites and most of tutorials and projects in github uses JSON
var ViewModel = {
dataList : ko.observableArray(data),
init: function() {
console.log(ViewModel.dataList);
}
};
this line
dataList : ko.observableArray(data),
when I try to call dataList it return this
function d(){if(0<arguments.length)return d.Wa(c,arguments[0])&&(d.X(),c=arguments[0],d.W()),this;a.k.Ob(d);return c}
and If I try to get its value console will tell me that dataList is not defined
but if I pass data directly to dataList like this (Which is not observableArray anymore) it will give me the full objects values in console
dataList : dataList,
the return value in console
[Object, Object]
how can I call the ko.observableArray from init function?
I want to follow the tutorials on the web like this one but my issue is the same.
http://opensoul.org/2011/06/23/live-search-with-knockoutjs/
Actually it's not only ko.observableArray arrays also I cannot call ko.observable objects
when I try to call dataList it return this
Your code doesn't call ViewModel.dataList, it just accesses it, which gives you the function (remember observables are functions). To call it, add ():
console.log(ViewModel.dataList());
// Note ----------------------^^

Backbone: Best way to handle variable common to all models

I'm currently developing my first Backbone single page app project and I'm facing an issue.
Basically I have a menu (html select input element) implemented as a View. Its value is used to control pretty much every other data requests since it specifies which kind of data to show in the other Views.
Right now I handle the DOM event and trigger a global event so that every model can catch it and keep track internally of the new value. That's because that value is then needed when requesting new data. But this doesn't look like a good solution because A) I end up writing the same function (event handler) in every model and B) I get several models with the same variable.
var Metrics = Backbone.Collection.extend({
url: "dummy-metrics.json",
model: MetricsItem,
initialize: function () {
this.metric = undefined;
},
setMetric: function (metric) {
this.metric = metric;
globalEvents.trigger("metric:change", this.get(metric));
}
});
var GlobalComplexity = Backbone.Collection.extend({
url: function () {
var url = "http://asd/global.json?metric=" + this.metric;
return url;
}, //"dummy-global.json",
model: GlobalComplexyItem,
initialize: function () {
this.metric = undefined;
this.listenTo(globalEvents, "metric:change", this.updateMetric);
},
updateMetric: function (metric) {
this.metric = metric.get("id");
this.fetch({ reset: true });
}
});
All my other Collections are structured like GlobalComplexity.
What's the cleanest way to solve this problem?
Thank you very much.
Define a global parametersManager. Export an instance (singleton) then require it when you need it.
On "globalupdate" you update the parametersManager then trigger "update" for all your model/collections so they'll look what are the current parameters in the parametersManager.

Can we change the value of attribute on after/before Create() callback in sails?

I have a scenario where I have to populate attribute of model with its id. For eg..
In User model:
module.exports = {
attributes: {
activation_link: "string"
},
afterCreate: function(value, cb) {
value.activation_link = "localhost:1337/user/action/"+ value.id;
cb();
}
The activation_link's modified value has to saved in the database too. How can that be achieved?
According to this and this your code should actually work: your manipulations in afterCreate are supposed to mutate the resulting object.
UPDATE
Hmm... Seems like the first parameter is not a Waterline object, despite of what the documentation says. Technically, you can refetch the record from DB by id, update and save without a lot of overhead (since it's supposed to be only called once upon creation). But I would really avoid putting in the DB a field that depends on a record id: such DB becomes untransportable, since you can't guarantee that the records will have the same ids. So, the solution would be either use some tokens for these activation links (the clean way) or just make activation_link a function without putting it in the DB (the simple way):
module.exports = {
attributes: {
},
activation_link: function() {
if (!this.id)
return false;
return 'localhost:1337/user/action/' + this.id;
}
}
Change from afterCreate to beforeCreate (sails -v 0.12.14)
beforeCreate: function (attrs, cb) {
attrs.createdAt = moment().format()
attrs.updatedAt = attrs.createdAt
return cb();
},
beforeUpdate: function (attrs, cb) {
attrs.updatedAt = moment().format()
return cb();
}
document here offical sails model lifecycle

Ember.js 'Objects' and 'ArrayController'

I'm getting my feet wet with a bit of Ember.js. I'm trying to create a super simple form that lets you submit a query.
App = Ember.Application.create();
App.QueryFormView = Ember.View.extend({
submitQuery: function () {
App.queries.pushObject({
firstName: this.get('name'),
message: this.get('message')
});
App.queries.save();
}
});
// Model
App.Query = Ember.Object.extend();
// Collection
App.queries = Ember.ArrayController.create({
content: [],
save: function () {
$.post('api/query', JSON.stringify(this.toArray()), function (data) {
// Queries saved
});
}
});
Each time the query form it submitted, I push an object to the queries ArrayController, and then run save.
However, I'm struggling to understand where the Ember.Object aka model comes into play. It's not being used at all here, and I'd like to know how to properly utilise it.
You don't have to use Ember.Object. If you never want to do any bindings, have calculated properties or observe any property changes, there's no need.
However if you do want to do any of those things you'd modify your code like this:
Document expected fields in the model.
// Model
App.Query = Ember.Object.extend({
firstName: null, // just to indicate what props you're expecting
lastName: null
});
Create your model object instead of anonymous object.
submitQuery: function () {
App.queries.pushObject(App.Query.create({ // .create() here
firstName: this.get('name'),
message: this.get('message')
});
App.queries.save();
}
And now for the big drawback. JSON.stringify() will serialize internal stuff you don't want. So each object sent over the wire must be simplified to the properties you want first. Help with this can be found here: Reflection on EmberJS objects? How to find a list of property keys without knowing the keys in advance
save: function () {
var obj = buildSimpleObject(this); // implements this somehow
$.post('api/query', JSON.stringify(obj.toArray()), function (data) {
// Queries saved
});
}

Categories