How do I separate data models and local-data models in Angular? - javascript

I hope I can expain myself what I mean.
Let's say I have a car resource. The car has the attributes color, name or whatever.
I get the list of cars using a service, something like cars.index().
But in the interface I have all the cars and when I click on one car, a little popup appears showing the inputs to edit the color and the name.
And here comes the issue. Where do I save the displayingInputs attribute?
Should I save it directly in the car resource and then just send the original attributes when submitting to the updated resource?
Should I create a new service called carWidget or something along the lines that each one has something like:
{
car: cars.get(carId),
displayingInputs: false
}
Should I store the displayingInputs inside a carWidget directive scope? What happens if I need to change the `displayingInputs from the parent scope? (for example when making a "display all"/"hide all" button)
Something else?
My best bet is #3, but I'm not sure how should I access the displayingInputs from outside the widget.

If you want to keep your car model clean, you can have a separate variable editedCar and display each popup with ng-show="car == editedCar".
If multiple cars can be edited at the same time, editedCars can be an associative array (car ID => boolean) and display popups using ng-show="editedCars[car.id]".
Another way not to send certain car properties is to prefix their name with a $ sign. This was simply use car.$displayingInputs. Be careful for name collisions as Angular uses this prefix to store internal data.
From the angular.toJson doc:
Serializes input into a JSON-formatted string. Properties with leading
$ characters will be stripped since angular uses this notation
internally.

Related

How to encapsulate some cucumber steps in one step? or in a parameter? or in tag?

Is there any possibility to call inside a scenario another scenario using tags?
How to encapsulate some cucumber steps in one step? or in a parameter? or in tag?
Eq.
#payload_car
Scenario: Populate Car payload
Given the user "x" populate the car payload
When the following information about car are introduced: type "Tesla", color "red", length "4.5m"
Then the Payload Car is populated
#car
Scenario: Select car
Given the user "y" is logged
When the user select the car "Tesla"
And populate the payload car #payload_car
Then the selected car contains all the details
Is it possible to call the scenario #payload_car when the #car scenario is called?
I mention that the scenario above is fictiv just to be more explicit...
Assuming you'd want to reuse those steps/scenarios:
you might be able to achieve the desired behaviour by doing the following:
You can pull the common behaviour in a Background (https://cucumber.io/docs/gherkin/reference/#background) (like the login)
And then leverage the capability of Scenario outlines (https://cucumber.io/docs/gherkin/reference/#scenario-outline), to test every combination that would lead to your Then steps.
But maybe I'm assuming wrong, can you give us a little more details about what you're trying to achieve?
No, you cannot call a scenario from another scenario.

Multiple search by ID. Search not knowing full ID. Sapui5

I was wondering if there was any option to search an element by its id but not knowing the full ID, only part of it. So I could find an element without knowing its full ID or find multiple elements with similar IDs.
For example if I knew I had 3 objects with the followings ID:
"objectID1" "objectID2" and "objectID3".
Could I something like:
getElementByID("objectID*")
I have tried it in JavaScript using: input[id*='PART_OF_ID_I_KNOW']
But it returns an HTML object and I need it for SAPUI5.
Could I use something like:
var myControl = sap.ui.getCore().byId('myId');
But not having to match the full ID (myID)? Thanks.
Though I would not recommend this but it's possible in a way as you describe it.You could look for elements with similar ID with jQuery, get the element's ID and pass it to sap.ui.getCore().byId();
var aElements = $("div[id*='PART_OF_ID_YOU_KNOW']");
//Lets say the first element returned is the one belonging to your control
var oControl = sap.ui.getCore().byId(aElements[0].id); //If the element is a SAPUI5 control, you should get it.
Why do you need to do this? Is it because you want to access controls (with prefixed IDs) inside your views and fragments? Did you give an ID of "myControl" to the control, but sap.ui.getCore().byId("myControl") doesn't work as the framework added a prefix to it?
If yes, the only reliable way to get a reference to your control is by using the framework provided methods in MVC views and controllers and in fragments.
If you have a control called "myButton" in your view, do this.byId("myButton") or this.getView().byId("myButton") from the controller to get a reference to your control.
If you have a control called "myButton" in a fragment that you embedded in your view via sap.ui.xmlfragment("", "myFragment.fragment.xml"), then use sap.ui.core.Fragment.byId("<prefix>", "myButton") to access it.
Whatever you do, don't make assumptions on how the framework creates these prefixed IDs. These are not documented and can change.
when you use `var myControl = sap.ui.getCore().byId('myId');`
it won't work.It is because when you try to get control by sap.ui.getCore() sapui5 automatically concat extra string to Your id egsap.ui.getCore().byId('xml0--myId') and if you have provided viewId in manifest then while rendering control it uses that. eg
sap.ui.getCore().byId('yourManifiestId--myId')

stocklist Dynagrid demo

I'm trying to modify the stocklist Dynagrid demo which is designed to work with HTML5 and Javascript, it's originally designed to subscribe an item per subscription.
In my case, I have connected this demo to my lightstreamer server, the adapter in my server deals with itemgroub and fieldschema instead of itemList and fieldList which was used in the example.
I modified the code to subscribe using this item group and equivalent field schema, now the dynagrid listener (onVisualUpdate function) is capable to detect how many items in the item group and based on that it creates the equivalent number of rows, however, when I call getChangedFieldValue for and one of the fields in the dynagrid, I get null always, and based of that no data is updated on the screen.
What is the solution for this problem, and how can I get the updated values?
(Note: Currently, I get the data directly from the info paramter which is passed to onVisualUpdate function).
When using a Field Schema, fields in the subscription are identified by their 1-based index within the schema and not by their name. So, wen you call getChangedFieldValue try to use the 1-based index to identify a field.

How do I pass an Eloquent model to a Knockout.js view model constructor?

I have a solution (see below), but it's awkward and klunky & I'd like to hear how others have solved this problem.
Here's a simple example to illustrate the problem:
Imagine I have an Eloquent User model and I'm putting together an "edit user" page that uses Knockout to handle value-to-DOM-element bindings.
In my controller method for this page, I'm doing the following:
public function getEditUser($id = null)
{
return View::make("account.edituser")
->with("user", User::find($id))
->with("groups", Group::all());
}
where the Group model is for my access control groups. The user can be a member of zero or more groups and the relationship is set up in the normal way for Eloquent models.
In the template, I have a bunch of elements (text, select, radio buttons, etc.) set up with data-bind attributes to bind my Knockout view model to the elements.
In the <script> portion of the page, I have the following:
var createUserViewModel = function (user, groups) {
return {
id: ko.observable(user.id),
name: ko.observable(user.name),
groups: ko.observableArray(user.groups),
// ...other attributes go here
// the list of available groups
availableGroups: ko.observableArray(groups)
};
};
// instantiate the view model
var viewModel = createUserViewModel(
// note that I'm using Smarty for my templating system. The
// lines below apply the json_encode method and disable the
// htmlspecialchars function which I have set up to encode
// all output by default
{$user|json_encode nofilter},
{$groups|json_encode nofilter}
);
ko.applyBindings(viewModel);
The user argument to the createUserViewModel function will be JSON-encoded, so it will look like this: { id: 1234, name: "Joe Smith", groups: ['group1', 'group2'], ...}
This is a simple example: I have several forms for entering other information which are significantly more complicated than this.
There are a couple of problems with this:
As I said, it's awkward. The source generated by this is difficult to read for larger models.
I suspect there's an XSS vulnerability here, since I'm echoing data via json_encode directly into the body of the script element. I haven't been able to exploit this, but I think someone else could find a way.
But I can't think of another way to do it that doesn't radically change the way the application works (ie. use AJAX calls to retrieve the data).
Can anyone share a better way to do this?
Re (1) you need to look at the very useful mapping which is designed for exactly this - http://knockoutjs.com/documentation/plugins-mapping.html ... this will replace the createUserViewModel function for you, and save you having to manually turn a JSON object into something observable.
Re (2) I'm not expert enough with security and XSS to give an authoritative answer, but it looks OK to me. So long as the user and group data was sanitised before you stored it, then it should be OK to echo it back as JSON. If you're not providing a textbox or other input for a user to type into that then affects this data then there's no angle for an attacker to inject a malicious script. Plus JSON-encoding itself is quite a good sanitisation, in that any JavaScript will just end up as a string. So to be sure, given:
{$user|json_encode nofilter}
will print out some JSON, you could immediately try JSON.parse on it:
var user = JSON.parse({$user|json_encode nofilter})
before you then do anything with it in your script.

Setting explicitly CouchDB document keys

CouchDB docs seem to have a key attached; it does not show up when retrieving a single document but you can use them to retrieve ranges of documents such as :
wget "http://localhost:5984/monitor20n/_all_docs?startkey=1111&endkey=2222
However, apparently that key is always the same as the document id, so that all you obtain is stuff like this
{"total_rows":14269,"offset":0,"rows":[
{"id":"128127896626798592","key":"128127896626798592","value":{"rev":"1-4e07e2c4b4eddfad5846ddf905337197"}},
{"id":"128128575021907970","key":"128128575021907970","value":{"rev":"1-43d983af1e837a4415b6167cae3b5de8"}},
... and so on }}
(see here key == id ). However, you can use more complex keys in views, including vectors which allow for much more complex interaction; at least, you can set the keys of views so you can now in advance what to search without looking up document ids.
The question is now: Can you set those keys up when creating a document? Or maybe after creating it?
An obvious workaround is to create a view like this
function (doc) {
emit(doc.key,doc)
}
however, I would like to know if there's a more direct way of obtaining the same effect.
Keys are an important part of CouchDB views. With a view, the key does not have to be the document ID. But the only way to produce a key is to use the emit function from within a view. There is no property that you can set that will automatically become the key.
Think of _all_docs like a built in view. To be consistent it follows the same output as a regular view, and it uses the id as the key. But you can't change the _all_docs view. If you wanted to provide your own _id when you save a document, that will end up being the key.
So if you wanted custom 'keys' in the '_all_docs' view you could create docs like this:
{ _id: 'Sample1' }, {_id: 'My2'}. and after they are saved, when you request the '_all_docs' view you would get:
{"total_rows":2,"offset":0,"rows":[
{"id":"Sample1","key":"Sample1","value":{"rev":"1-4e07e2c4b4eddfad5846ddf905337197"}},
{"id":"My2","key":"My2","value":{"rev":"1-43d983af1e837a4415b6167cae3b5de8"}},
... and so on }}
Here is a link about what makes a documentID:
http://wiki.apache.org/couchdb/HTTP_Document_API#Special_Fields
While it does not say explicitly, you can't use objects or arrays as DocumentIDs.
Hope that helps.

Categories