I've been tasked with creating a webapp using AngularDart. I'm new to Dart and therefore AngularDart also, but have worked through the tutorials at https://angulardart.org/tutorial/.
I've read similar SO questions/answers (How to access a AngularDart components attribute (NgOneWay) outside of the component, eg. on the page it is in?) but given my limited knowledge I don't fully understand how to implement Brian's suggestion - or if indeed it relates to my question! Am I also right in thinking that Vink's suggestion is now irrelevant as #Controller's are now deprecated?
In short, I'm trying to figure out if the following is in fact achievable:
create a top-level <custom-component/> complete with attributes;
within <ng-view/> - and therefore nested components - access <custom-component/>'s attributes. More specifically, bind/listen for changes to these attributes and act accordingly.
For example, given the following
<body>
<custom-component att1="val1" att2="val2"></custom-component>
<ng-view></ng-view>
</body>
and on the assumption that <ng-view/> renders the following markup
<div>
...
<other-component att1="{{customComponent.att1}}" att2="{{customComponent.att2}}"></other-component>
<another-component att1="{{customComponent.att1}}" att2="{{customComponent.att2}}"></another-component>
...
</div>
is it possible to bind customComponent.<<attributeName>> to <other-component/> and <another-component/>?
Or, as is likely, am I misunderstanding the use of AngularDart's #Component/#Decorator?
Should the #att1 and #att2 attributes be moved from <custom-component/> to <ng-view/>?
Alternatively, should I look to architect a different solution altogether? My ultimate goal in this instance is to provide the user with att1/att2 select boxes (from yet another component) which in turn determine the rendered content within each of <other-component/> and <another-component/>.
Any and all suggestions welcome, I won't be offended if you dismiss any/all of the above!!!
My current development environment is as follows:
Dart SDK version 1.9.0-dev.8.0
angular 1.0.0
Many thanks, J
What you can do is to move the two components into the content(template) of a wrapper component and bind attributes of both components to fields of the wrapper element.
Usually a better way is to use events like shown in How to communicate between Angular DART controllers or Angular Dart component events (controllers have been merged with components since then)
Related
Once I switch my context to the DOM of the webview, I want to be able to search those elements by tag, but I get the error that searching by tag is deprecated and to search by class instead. This won't work to find DOM elements by tag. Is there still a way to do it? Thanks!
As per Appium documentation for migrating to 1.0:
We've removed the following locator strategies:
-name
-tag name
... tag name has been replaced by class name. So to find an element by its
UI type, use the class name locator strategy for your client.
Why searching by tag name?
Although Selenium still supports this type of query, Appium decided not to do anymore. Actually when interacting with the device, searching by tag name is very inefficient.
Why would you want to do that? Think about it, if your page has a bit of content, you will end up having many p, div, span tags. Your search will return many elements and then you will have to go thorugh the list and locate the one you are interested in. If your page is very little, then you will probably end up with one tag of the type you are looking for, however why not applying a class and solve the problem?
Classes are not for CSS style
Remember that HTML attribute class was not introduced by W3C for applying CSS style. It is used to provide an element with more informationa bout its purpose in the DOM. When you apply a class to an element, you should do that basing on the role that element holds! Thus locating an element by class is sure better.
So forget searching by tag name. You should change your strategy and apply class names to your tags in your hybrid app. If you do not want to do so, then do not switch to the new version of Appium but this will keep you far from future innovations!
Migrating from a tagname based element location to a class name
orientd one is good practice. That's why you should change too.
maybe this can help
element.getAttribute("class")
I'm currently struggling with the problem of multilingualism in an SPA.
I've come up with several solutions, like building a wrapper for the resources resx files, or saving all labels in the database, but I am wondering if any of you have found some solution which automates these steps.
Are there any practices which are specific for this problem?
For a reasonable amount of literals, I suggest to save the resources in the DB or in a .RESX file in the server. When the user logs in or you detect the language that will be used, the literals are requested by the application and saved either in a collection of your translation module or in the LocalStorage of the browser (this could be a good approach for large data).
Then this module could have some methods to retrieve the messages, probably passing a key.
Using this solution you could inject this module in the viewmodels that need to show translated literals and acces them through the view:
<p data-bind="text: resourceManager.get('M01')"></a>
For large applications that would require huge localization data to be transfered, maybe some kind of modularity could be applied and only load the resources really needed for each module/section.
I don't think making recurrent requests to the server to get the translated literals is a good practise. SPA's should provide a good user experience and loading the translated literals from the server could be a blocking issue. Text is not like an image, you can render a page without all the images loaded, imagine rendering a page without the text :o
Anyway, I think the best solution would be to keep the server as repository and create a custom JS module that takes care to get data in one or multiple loads and is able to store it somewhere in the client.
I've solved my own problem, using a custom binding and i18next.
First, I've implemented i18next for translation of my labels/buttons and other resources.
Secondly, I've added a custom Knockout bindingHandler:
ko.bindingHandlers.i18n = {
init: function (element, valueAccessor) {
var translateKey = valueAccessor();
ko.utils.setTextContent(element, $.t(translateKey));
}
};
Finally you can add the following code to your views:
<span data-bind="i18n : 'buttons.cancel'"></span>
This will automatically get the correct resource, and Knockout will handle the bindings.
Hopefully this will help others struggling with the same problem.
Angular newb here, thoughts appreciated...
Say I want an input field to control the window title as you type. A field with a model binding and no associated controller acts on keypress, as intended. However, there has to be a bit more logic to it -- default value before any user input, also used if the input is blanked.
Adding a controller bound to enclosing elements gives a place for that logic, but the change-on-keypress behavior is gone. I'm sure it's possible to recreate it by hand or with ui, but since it's inherently there without the controller, I'm wondering if I'm missing the simple clean way.
Simple version, acts on keypress, but with no smarts:
<title ng-bind-template="{{windowTitle}}">Default Title (not seen)</title>
<input ng-model="windowTitle" type="text">
Putting controller bindings on the head (for the title) and a containing div (for the input), and setting a default $scope.windowTitle inside the controller function does use that default value, but it breaks the auto-update.
I know in real life you'd want a real model, but what I'm really trying to understand is these two ways angular appears to work. I haven't found anything specifically describing two different implicit input binding behaviors, but I haven't been through all the docs yet.
How should I be thinking about this?
Edit: It's not the window title or default value per se that I'm interested in. I'm trying to understand this:
When there's no controller on either the field or the title, typing in the field changes the window title immediately, on keypress. The title is directly linked to the field value, with no other angular hookup.
With controller bindings around the title and the field, typing in the field has no effect on the title.
What I've since realized (I think) is that ng-controller bindings create a new instance of the controller each time. Here's the non-working code I didn't show before:
<title ng-controller="TitleCtrl" ng-bind-template="{{windowTitle || 'Foo'}}">Foo</title>
...
<label ng-controller="TitleCtrl">
<input ng-model="windowTitle" type="text">
{{windowTitle}}
</label>
The value set by the model binding to the field is shown correctly within that instance of that controller, and updates on keypress, as before. But since those two controller instances are separate, the binding to the title works but the data it points to isn't bound to the field.
Isn't that right? The reason it works with no controllers is that that makes the value global, so the title binding sees the value set by the field binding.
So what's the canonical way to reference data from some other area? Create a service?
I realize that this is basic angular stuff, just getting started here, so thanks!
Edit 2
On reflection, I've come to seriously disrespect this whole question, even though I wrote it.
It's based on way-too-early poor understanding of the Angular application model. I had worked through only part of the official tutorials, and jumped ahead to removing all the js from a not big but not totally trivial existing app, and exploring what Angular could to in that context.
I got some very quick bang for the buck, getting several pieces of functionality working with very little code, and simple, clear markup, felt good. But I really had short-circuited internalizing the Angular way of thinking, and my quick and dirty no-architecture approach broke down when different parts of the page needed to coordinate with each other, as in this question.
I've postponed that project while I go back to tutorials and other learning. If other folks think this question should be deleted, I'd add my vote. Or maybe it's a useful on some level, ignorant though it is.
Well, there are multiple ways to achieve the behavior you want without using an explicit controller and model, you could:
<title ng-bind-template="{{windowTitle && windowTitle || 'default'}}"></title>
Or in a more simple way:
<title>{{windowTitle && windowTitle || 'default' }}</title>
In both cases, we're using the conditional expression:
(condition) && (answer if true) || (answer if false)
You should however strive to remove logic from the templates.
I'm using Rails 3 to create a project that will need a model called Sketch. I've already created a model, controller, and migration to handle Sketch - so far it just creates a 'sketch' object with a name for each sketch.
My problem is that I need to be able to attach an html5 canvas to each sketch object when it is created (or remove it when it is destroyed).
Since 'canvas' is not a datatype that will be stored in the database (like 'string', 'integer', or 'datetime'), how do I go about creating custom html components such as this that need to be treated like any other datatype in a Rails app?
I'm assuming that you would need to add the html components to a Model method and use a callback - like after_save - to initiate the component. But I'm not sure at all how to do this.
Not sure if I'm describing this well enough, so here is a very simple mockup:
I have the Raphael Javascript library in mind for the component that will do the sketching - if that helps.
If you can point me to any tutorials on this subject that would be great.
HTML5 canvases are rendered in the browser, not on the server where your ruby code is actually executed. Therefore I think it's safe to say that what you're asking isn't possible (at least in the way the question is phrased).
Instead you'll need to work with HTML, CSS and Javascript in your view to get the canvas working.
Canvas Tutorial / Reference
Hope this helps.
(On a related note, it's also considered a bad practice to mix view-related concepts in with your models.)
Tagsoup is interfering with input and formatting it incorrectly. For instance when we have the following markup
Text outside anchor
It is formatted as follows
Text outside anchor
This is a simple example but we have other issues as well. So we made tagsoup cleanup/formatting optional by adding an extra attribute to textarea control.
Here is the diff(https://github.com/binnyg/orbeon-forms/commit/044c29e32ce36e5b391abfc782ee44f0354bddd3).
Textarea would now look like this
<textarea skip-cleanmarkup="true" mediatype="text/html" />
Two questions
Is this the right approach?
If I provide a patch can it make it to orbeon codebase?
Thanks
BinnyG
Erik, Alex, et al
I think there are two questions here:
The first Concern is a question of Tag Soup and the clean up that happens OOTB: Empty tags are converted to singleton tags which when consumed/sent to the client browser as markup gets "fixed" by browsers like firefox but because of the loss of precision they do the wrong thing.
Turning off this clean up helps in this case but for this issue alone is not really the right answer because we it takes away a security feature and a well-formed markup feature... so there may need to be some adjustment to the handling of at least certain empty tags (other than turning them in to invalid singleton tags.)
All this brings us to the second concern which is do we always want those features in play? Our use-case says no. We want the user to be able to spit out whatever markup they want, invalid or not. We're not putting the form in an app that needs to protect the user from cross script coding, we're building a tool that lets users edit web pages -- hence we have turned off the clean-up.
But turning off cleanup wholesale? Well it's important that we can do it if that's what our usecase calls for but the implementation we have is all or nothing. It would be nice to be able to define strategies for cleanup. Make that function plug-able. For example:
* In the XML Config of the system define a "map" of config names to class names which implement the a given strategy. In the XForm Def the author would specify the name from the map.
If TagSoup transforms:
Text outside anchor
Into:
Text outside anchor
Wouldn't that be bug in TagSoup? If that was the case, then I'd say that it is better to fix this issue rather than disable TagSoup. But, it isn't a bug in TagSoup; here is what seems to be happening. Say the browsers sends the following to the client:
<a shape="rect"></a>After<br clear="none">
This goes through TagSoup, the result goes through the XSLT clean-up code, and the following is sent to the browser:
<a shape="rect"/>After<br clear="none"/>
The issue is on the browser, which transforms this into:
<a shape="rect">After</a><br clear="none"/>
The problem is that we serialize this as XML with Dom4jUtils.domToString(cleanedDocument), while it would be more prudent to serialize it as HTML. Here we could use the Saxon serializer. It is also used from HTMLSerializer. Maybe you can try changing this code to use it instead of using Dom4jUtils.domToString(). You'll let us know what you find when a get a chance to do that.
Binesh and I agree, if there is a bug it would be a good idea to address the issue closer to the root. But I think the specific issue he is only part of the matter.
We're thinking it would be best to have some kind of name-to-strategy mapping so that RTEs can call in the server-side processing that is right for them or the default if it's not specified.