In AngularDart I used to extend ShadowRootAware and AttachAware to query the document with shadowRoot.querySelector(...).
Now it seems that those classes are gone. How can I query the DOM, and how do I execute some code in the "attach" phase?
I found
var shadowRoot = DOM.getShadowRoot(host);
shadowRoot should allow you to call querySelector()
Not tried myself yet though.
Related
Once again, a Dart/Polymer related question.
I wanted to use the Parse.com JavaScript library, but since it's not available in Dart I've written Wrapper classes which store a JsObject and delegate all calls from Dart to the corresponding JavaScript object. Basically it's like a proxy.
Guess what, it works pretty great.
However, my observables don't. To understand this, you have to take a look at the following structure of one of my "proxy"-classes.
class ParseObject extends Observable {
JsObject _jsDelegate = new JsObject(context['Parse']['ParseObject']);
void set(String key, dynamic value) {
_jsDelegate.callMethod('set', [key, jsify(value)];
}
dynamic get(String key) {
return dartify(_jsDelegate.callMethod('get', [key]));
}
}
The HTML code of my Polymer Element looks like this:
<div>Name: {{project.get('name')}}</div>
Since the data binding is only evaluate in case the parameter of the method changed, it will never be updated and thus even though the name is changed, the old one will stay in place.
The solution I came up with is to store all the values the user is setting in the ParseObject#set(String, dynamic) method into a Map which is observable. This works but I think it's quiete dirty since I have to make sure that both Maps, the one in Dart and the one in the ParseObject's JavaScript representation equal.
Thus I am looking for a better solution and I think of some kind of method to tell Polymer to reevaluate it's data bindings.
Does such a method exist or are there any other possibilities to address this problem?
Extending observable by itself does nothing yet.
You need to annotate the getters with #observable (and if you are not using Polymer, you also need to add the observable transformer to pubspec.yaml). You can't make functions observable (this works in Polymer elements but not in Observable model classes. For more details about observable see for example Implement an Observer pattern in Dart or Dart: #observable of getters
I am trying to pass an object reference to the Dart script associated with a Polymer element. I have found the element in the DOM but I can't figure out how to call a method in the Dart associated with the element or any other way to dynamically pass an object to the Polymer element to be displayed.
Basically you just get a reference by using for example querySelector('#someid') and just assign the value to a field or setter or call a method and pass it as an argument.
querySelector('#someid').someField = someValue;
querySelector('#someid').setValue(someValue);
This might produce a hint in DartEditor but should still work when the code is executed. To get rid of the hint you can "cast" like
(querySelector('#someid') as MyComponent).someField = someValue;
querySelector('#someid') as MyComponent).setValue(someValue);
You need to import MyComponent to make this work.
If this doesn't something with your code might be wrong. For example the main() method if you have one. See how to implement a main function in polymer apps for more details.
If nothing of the above works, please add code to your question that shows what you're trying to accomplish.
I have a custom #NgComponent in my project and it works if I place it within the static HTML of the application. What I'm trying to figure out is how to add one to the DOM dynamically? If I construct an instance of my Component it does not appear to be of type Element and so it cannot be added directly to the children of an element in the DOM. Is there an alternate way to construct my component or wrap it for injection into the DOM?
e.g. I naively expected to be able to do something like:
dom.Element holderEl = dom.document.querySelector("#my-holder");
holderEl.children.add( new MyComponent() );
But I have also tried simply appending HTML containing my custom element to an element using innerHTML
holder.innerHtml="<my-component></my-component>"
and creating the element using document.createElement()
dom.Element el = dom.document.createElement("my-component");
dom.document.body.append(el);
But the component does not seem to be realized when added.
thanks,
Pat
You can add components dynamically, but you must manually invoke the Angular compiler so it notices that the innerHTML has a component embedded in it.
However, that is not the "Angular way".
Instead, write your template as
<div id="my-holder">
<my-component ng-if="should_component_be_displayed"></my-component>
</div>
Here, my-component will be created and included in the DOM only if should_component_be_displayed is true.
The my-holder div can be removed which leads to a cleaner DOM structure.
Is there a procedure to call an "init" method on a polymer element in Dart in order to populate it?
I have a polymer template (still not sure it's correct) and I want to populate it with the results of an HttpRequest. I can populate with a static list, but not sure how to populate it with a dynamic list made via an http call.
Are there examples anywhere?
I'm still trying to come up to speed on Dart and Polymer ...
My hacks are at https://gist.github.com/fils/6270699
Have you considered putting the init code inside a created() lifecycle method? You can see an example of that at https://github.com/dart-lang/web-ui/blob/polymer/example/todomvc/web/todo_row.dart
I have written a jquery-ui widget using the Widget Factory...
I need to be able to determine in code whether the element is already a widget or not...
My investmentGrid widget is created on #container with
$('#container').investmentGrid()
I need to be able to determine elsewhere in the code if $('#container') is already an investmentGrid
You can query the element's jQuery.data() function, like so:
if ($('#container').data('investmentGrid')) {
...
}
You could try the pseudo selector that is created for you when using the widget factory. $(":namespace-widgetname")
#dan-story may have had the answer at the time he answered it, but I have found that that method doesn't work anymore. Well, not entirely. At least not with jQueryUI 1.10. According to the documentation at http://api.jqueryui.com/jQuery.widget/ in the "Instance" section, you now need to have the widget's full name.
For example, if you create your widget factory with this:
$.widget("Boycs.investmentGrid", ...);
Then, to check if container has it, you would check with this:
if ($('#container').data('Boycs-investmentGrid'))
{
...
}
It is no longer enough to just use the name.
#Boycs: As per my understanding, using Widget Factory protects you from instantiating a plugin multiple times on the same element. (ref: http://jqueryui.pbworks.com/widget-factory)
In addition if you want to confirm if "container" is already an investment grid you can try the following option from inside your plugin code:
this.element.data("investmentGrid")
=== this;
For more details you can refer to docs.jquery.com/UI_Developer_Guide
Current versions of jQuery UI (I can confirm it with 1.11.x) allow you to query for an instance of a widget via the instance() method. This will then look like this:
$('#container').investmentGrid('instance')
If the element does not have an investmentGrid widget assigned, you will get undefined back.
You may also use call this instead:
$(#container').is(':data("namespace-investmentGrid")')
This has the advantage, that it also works even when the widget is not loaded.