I am attempting to refactor some dart-polymer components to use the #HtmlImport annotation.
.dart
part of epimss_shared.components;
#CustomTag('associated-symptoms-form')
class AssociatedSymptomsForm extends PolymerElement {
AssociatedSymptomsForm.created() : super.created();
#override
void attached() {
super.attached();
}
}
.html
<polymer-element name='associated-symptoms-form'>
<template>
<div layout horizontal center>
<h1>Symptoms</h1>
</template>
<script type = 'application/dart' src='associated_symptoms_form.dart'></script>
</polymer-element>
library
The library epimss_shared.components; is part of the imported epimss.shared library.
#HtmlImport('../components/tooltip/tool_tip.html')
#HtmlImport('../components/misc/associated_symptoms_form.html')
library epimss_shared.components;
import 'dart:html' as dom;
import 'package:polymer/polymer.dart';
import 'package:epimss_shared/epimss_shared.dart';
import 'package:epimss_shared/epimss_shared_client.dart';
part '../components/tooltip/tool_tip.dart';
part '../components/misc/associated_symptoms_form.dart';
When I attempt to use the component, the application is not displayed with the following console error:
'package:epimss_shared/components/misc/associated_symptoms_form.dart': error: line 1 pos 6: url expected
part of epimss_shared.components;
^: package:epimss_shared/components/misc/associated_symptoms_form.dart
The peculiar thing is this - if I creat a new component with a different name with everything remaining the same (as done with the tooltip component shown in the library) there is no problem at all!
It seems that previous information of the component is cached and is being reused.
Any help is appreciated.
Related
I have a dart app that contains a template with a material-checkbox which I am unable to use in my component. Here is a simple template to demonstrate the problem (two_boxes.html):
<!--
Simple HTML to test checkboxes
-->
<input type="checkbox" id="cb0">
<label>Standard Checkbox</label>
<material-checkbox label="Material Checkbox" id="cb1">
</material-checkbox>
<button (click)="doTest()">Test</button>
and the corresponding component in which I try to use the checkboxes (two_boxes.dart). I can use the standard checkbox in a cast as expected but cannot find a way to do the same with the material checkbox:
// Component for testing
import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
import 'dart:html';
#Component(
selector: 'two-boxes',
templateUrl: 'two_boxes.html',
directives: const [MaterialCheckboxComponent],
pipes: const [
COMMON_PIPES
])
class TwoBoxes {
// Get the the two checkboxes and see if they are checked
void doTest() {
var checkbox_standard = querySelector("#cb0");
print(checkbox_standard.runtimeType.toString()); // InputElement
print((checkbox_standard as CheckboxInputElement).checked); // Succeeds
var checkbox_material = querySelector("#cb1");
print(checkbox_material.runtimeType.toString()); // HtmlElement
print((checkbox_material as MaterialCheckboxComponent).checked); // Error!
}
}
The last statement fails when I run the app in Dartium following a "pub serve" (no errors) with:
VM54:1 EXCEPTION: type 'HtmlElementImpl' is not a subtype of type
MaterialCheckboxComponent' in type cast where HtmlElementImpl is
from dart:html MaterialCheckboxComponent is from
package:angular_components/src/components/
material_checkbox/material_checkbox.dart
Clearly this way of casting does not work. I searched for hours how to solve this error and find the correct way to do this but obviously in the wrong places. What am I missing here? I am using Dart VM version 1.24.2.
There is no way to get the component instance from an element queried this way.
You can use #ViewChild()
class TwoBoxes implements AfterViewInit {
#ViewChild(MaterialCheckboxComponent) MaterialCheckboxComponent cb;
ngAfterViewInit() {
print(cb.checked);
}
to get a specific one if you have more than one, you can use a template variable
<material-checkbox #foo label="Material Checkbox">
with
#ViewChild('foo') MaterialCheckboxComponent cb;
You can find more information about this topic in this TypeScript answer angular 2 / typescript : get hold of an element in the template
The syntax is a bit different (type annotations on the right and {} around the optional read parameter, which are not used in Dart.
This is my polymer.dart class.
import 'package:polymer/polymer.dart';
/**
* A Polymer x-changer element.
*/
#CustomTag('x-changer')
class XChanger extends PolymerElement {
#published String prop;
propChanged() {
print("prop changed!");
}
/// Constructor used to create instance of XChanger.
XChanger.created() : super.created() {
}
}
This is my project structure:
example
chat_example
lib
web
lib
x-changer.dart
x-changer.html
test
When I add x-changer.dart & x-changer.html in my example folder it works. It is exactly the same code, am I missing something that is important for a polymer element library?
EDIT:
This is the library pubspec
name: some_elements
description: >
The polymer elements for ...
version: 0.0.1
author: Joris Hermans
#homepage: https://www.example.com
dependencies:
polymer: '>=0.15.4 <0.16.0'
dev_dependencies:
unittest: any
You need to add the polymer transformer in the library (without entry_points).
You shouldn't import like You shouldn't import like`
It should look more like
You shouldn't import like <link rel="import" href="packages/chat_example/force/force_client_element.html">
You might need one or more additional ../ prefixes, depending on where the importing file resides (this is never necessary in Dart package:xxx imports.
<link rel="import" href="../packages/chat_example/force/force_client_element.html">
See https://www.dartlang.org/polymer/app-directories.html for more details.
I'm playing around a bit with custom elements and custom attributes with Polymer.dart, but I can't find out what the line super.attached does.
<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="kp-volume">
<template>
<p>You turned the volume to {{volume}}.</p>
</template>
<script type="application/dart">
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('kp-volume')
class KPVolume extends PolymerElement {
KPVolume.created() : super.created();
#published int volume = 0;
void attached() {
//where do I need this line for ?
super.attached();
volume = 5;
}
}
</script>
</polymer-element>
So I get that if I change the volume in the attached function, that then I can override HTML code like this <kp-volume volume="11"></kp-volume>. But there doesn't seem to be a difference in using super.attached or not. What does this line do ?
attached is a method in the super class PolymerElement which does the actual attaching of the element to the DOM.
If you override the method in a subclass the attached method of the super class is disable and therefore the element will never be attached.
By overriding a method you replace it's default implementation.
By calling super.attached() you invoke the default implementation in PolymerElement and reuse the default implementation in your replacement.
You can add your custom code before or after the super.attached() line so your custom code will be execute before and/or after the default attach logic.
Overriding attached and not calling super.attached(); will break your element. Maybe your example element is just too simple to notice.
Other lifecycle methods like ready, domReady don't need the call to the super implementation because the default implementation is an empty function.
(xxxChanged lifecyle methods are yet another kind, they don't exist in the super class at all).
Im new with this language and this framework, Ive made a command-line app and it works perfectly and now I wanna make a very simple web interface
I have this in my .html
<body ng-app>
.
.
.
<input type="submit" ng-click="doSomething()">
In my .dart
import 'dart:html';
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
.
.
.
void doSomething(){
lotToDo;
}
And I get this
Property 'doSomething' is not of type function.
Whats the point of the error ? Its necesary to use a controller ?
Thanks to all !
You need a controller that contains the doSomething() method.
See https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_03/lib/recipe_book.dart for example.
The index.html has a tag <body recipe-book> tag. Angular applies the controller declared in recipe_book.dart here because this controller has the selector selector: '[recipe-book]' assigned which is a tag that has the attribute recipe-book.
You also need to initialize a module so Angular knows of this controller.
library recipe_book;
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
import 'package:angular_dart_demo/rating/rating_component.dart';
import 'package:angular_dart_demo/recipe_book.dart';
class MyAppModule extends Module {
MyAppModule() {
type(RecipeBookController); // register controller in a module
type(RatingComponent); // register some other component
}
}
void main() {
applicationFactory()
.addModule(new MyAppModule()) // tell angular to use the modul declared above
.run();
}
My advice: work through this tutorial before trying random things https://angulardart.org/tutorial/
I am trying to create custom element using the following:
import 'package:polymer/polymer.dart';
// Custom elements extend PolymerElement
#CustomTag('my-element')
class MyElement extends PolymerElement {
// custom functionality goes here
}
Dart Editor shows error 'Undefined name CustomTag
I am trying the example given at the URL below. All files are copied as listed at the URL below.
https://github.com/sethladd/dart-polymer-dart-examples/blob/master/web/custom_element_that_contains_other_tags/my_element.dart
Am I missing something in pubspec? pubspec is not listed at the above URL.