As the title of the question. I have one swf that loads other swf files using createEmptyMovieClip, loadMovie and for the destroy removeMovieClip, and delete.
Each external swf file has the same name class with the other loaded.
After loading the external swf files the view part works perfect! But the class its always the first loading ....
any suggestions?
loader.swf - file_loader.as
class file_loader extends MovieClip
{
public var tmpMC:MovieClip;
public function file_loader()
{
}
function onLoad()
{
var that = this;
this["btn_a"].onPress = function() {
that.loadFile("file_a.swf");
}
this["btn_b"].onPress = function() {
that.loadFile("file_b.swf");
}
}
function loadFile(filename:String):Void
{
tmpMC.removeMovieClip();
delete tmpMC;
tmpMC = new MovieClip();
tmpMC = _parent.createEmptyMovieClip("tmpMC", -16384);
tmpMC.loadMovie(filename);
}
}
file_a.fla - mainClass.as
class mainClass extends MovieClip
{
public function mainClass()
{
}
function onLoad()
{
this["txt"].text = "file_a.swf: function onLoad()";
}
}
file_b.fla - mainClass.as
class mainClass extends MovieClip
{
public function mainClass()
{
}
function onLoad()
{
this["txt"].text = "file_b.swf: function onLoad()";
}
}
Related
I am new to Aurelia. I have a WebApi that will return some data that I would like to populate into my exported model and then display the info on the screen.I'm thinking it would go into my run event but am not sure. Can anybody tell me how to do this . Any information would be most appreciated. My code is below.
--Jason
import 'fetch';
import {HttpClient, json} from 'aurelia-fetch-client';
import {inject} from 'aurelia-dependency-injection';
declare var window: { wcApiUrl: string, wcAmtInstanceId: string };
#inject(HttpClient)
export class BureauModUpdate {
files: string;
constructor(private http: HttpClient) {
http.configure(x => {
x.defaults.headers = { 'Authorization': 'Basic ' + window.wcAmtInstanceId }
});
}
public run(): void {
//Would I put it here ??
}
upload(): void {
var form = new FormData()
for (var i = 0; i <= this.files.length; i++) {
form.append('file', this.files[i])
this.http.fetch(window.wcApiUrl + '/Lookup/BureauModUpdate/CreateBureauModUpdates', {
method: 'post',
body: form
})
}
}
}
export class BureauModUpdateHistory {
public IndexId: number;
public UploadID:number;
public EmployeeNum: number;
public filename: string;
public Bureau: string;
public UploadedDate: Date;
public UploadedStatus: string;
public ErrorInfo: string;
public RecordCount: number;
}
To make something happen when the page loads, use the attached() Aurelia component lifecycle method, like this:
attached() {
// do something here
}
For more information on the Component Lifecycle, see the documentation on Aurelia's DocHub.
Example using Fetch to get data:
For getting HTTP data using fetch (or any other web service), you need to use an async call (using .then to chain the next event). For example:
this.http.fetch(url).then(response => {
this.data = response;
}
Then, just bind your data to this.data (depending on what type of data you're getting). For example:
<template>
Hello, ${data.fname}!
</template>
I am having trouble with creating a custom element that will be used like
<shimmy-dialog type="video" href="/test">Hi</shimmy-dialog>
The custim element will replace this code with a href that when clicked should popup a dialog of a particular type.
Everything seems to work up until the point I try to open the dialog.
This is when I get the error
Unhandled rejection TypeError: Cannot set property 'bindingContext' of null
I do sometimes find the Aurelia errors a little cyptic.
I suspect it has something todo with the element not having a view.
The code is as follows
enum DialogType {
video = 1,
iframe
};
#inject(Bcp, DialogController)
export class ShimmyDialogModel {
private type : DialogType;
constructor(private bcp: Bcp, private controller : DialogController){
console.log("here");
}
async activate(state){
this.type = state['type'];
}
get isVideo() : boolean {
return this.type == DialogType.video;
}
get isIframe() : boolean {
return this.type == DialogType.iframe;
}
}
#noView
#processContent(false)
#customElement('shimmy-dialog')
#inject(Element, App, Bcp, DialogService)
export class ShimmyDialog {
#bindable public type : string;
#bindable public href;
#bindable public name;
private originalContent : string;
constructor(private element: Element, private app: App, private bcp: Bcp,
private dialogService: DialogService) {
this.originalContent = this.element.innerHTML;
}
bind() {
this.element.innerHTML = '' + this.originalContent + '';
}
attached() {
let self = this;
this.type = this.element.getAttribute("type");
let dialogType = DialogType[this.type];
this.element.children[0].addEventListener("click", function(){
if(dialogType == DialogType.iframe) {
self.dialogService.open({ viewModel: ShimmyDialogModel, model: {'type' : dialogType}}).then(response => {
});
}
else if(dialogType == DialogType.video) {
self.dialogService.open({ viewModel: ShimmyDialogModel, model: {'type' : dialogType}}).then(response => {
});
}
return false;
});
}
async typeChanged(newValue) {
this.type = newValue;
}
async hrefChanged(newValue) {
this.href = newValue;
}
}
The template for the dialog is below.
<template>
<require from="materialize-css/bin/materialize.css"></require>
<ai-dialog>
<ai-dialog-header>
</ai-dialog-header>
<ai-dialog-body>
<div if.bind="isVideo">
Video
</div>
<div if.bind="isIframe">
IFrame
</div>
</ai-dialog-body>
<ai-dialog-footer>
<button click.trigger="controller.cancel()">Close</button>
</ai-dialog-footer>
</ai-dialog>
</template>
Thanks for any help.
I solved this by seperating the classes into their own files.
Aurelia did no like having two export classes there.
I'd like to achieve something similar as "include" in android but in aurelia:
How to inject a plain html file content into my view, with binding evaluated within the parent View, and without using a custom element?
Binding innerhtml is not enough as, according to the doc, the bindings expressions are bypassed.
As already said by Ashley, using <compose view="./your-view.html"></compose> element will work with an existing HTML file and it will inherit the parent context.
If you want to compose HTML dynamically (from a file, database, or built-up programmatically) then using the ViewCompiler will give you the best performance and flexibility, as this is one layer less than compose compared to how aurelia builds custom elements internally.
I gave a similar answer to a different (but related) question here:
Aurelia dynamic binding
You'd use the text plugin to load your HTML file as text into a variable, and then pass that to the ViewCompiler. I have a custom element for this which, in terms of performance, is probably not better than compose but it does allow for more control when working with raw html as input and you could do your own performance optimizations specific to your situation as needed:
import * as markup from "text!./your-element.html";
export class SomeViewModel {
constructor() {
this.markup = markup;
}
}
And the view:
<template>
<dynamic-html html.bind="markup"></dynamic-html>
</template>
For completeness sake, here is the custom element I encapsulated the ViewCompiler in:
import {
customElement,
TaskQueue,
bindable,
ViewCompiler,
ViewSlot,
View,
ViewResources,
Container,
ViewFactory,
inlineView,
inject,
DOM
} from "aurelia-framework";
#customElement("dynamic-html")
#inlineView("<template><div></div></template>")
#inject(DOM.Element, TaskQueue, Container, ViewCompiler)
export class DynamicHtml {
#bindable()
public html: string;
public element: HTMLElement;
private tq: TaskQueue;
private container: Container;
private viewCompiler: ViewCompiler;
private runtimeView: View;
private runtimeViewSlot: ViewSlot;
private runtimeViewFactory: ViewFactory;
private runtimeViewAnchor: HTMLDivElement;
constructor(element, tq, container, viewCompiler) {
this.element = <HTMLElement>element;
this.tq = tq;
this.container = container;
this.viewCompiler = viewCompiler;
}
public bindingContext: any;
public overrideContext: any;
public bind(bindingContext: any, overrideContext: any): void {
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
if (this.html) {
this.htmlChanged(this.html, undefined);
}
}
public unbind(): void {
this.disposeView();
this.bindingContext = null;
this.overrideContext = null;
}
public needsApply: boolean = false;
public isAttached: boolean = false;
public attached(): void {
this.runtimeViewAnchor = <HTMLDivElement>this.element.firstElementChild;
this.isAttached = true;
if (this.needsApply) {
this.needsApply = false;
this.apply();
}
}
public detached(): void {
this.isAttached = false;
this.runtimeViewAnchor = null;
}
private htmlChanged(newValue: string, oldValue: void): void {
if (newValue) {
if (this.isAttached) {
this.tq.queueMicroTask(() => {
this.apply();
});
} else {
this.needsApply = true;
}
} else {
if (this.isApplied) {
this.disposeView();
}
}
}
private isApplied: boolean = false;
private apply(): void {
if (this.isApplied) {
this.disposeView();
}
this.compileView();
}
private disposeView(): void {
if (this.runtimeViewSlot) {
this.runtimeViewSlot.unbind();
this.runtimeViewSlot.detached();
this.runtimeViewSlot.removeAll();
this.runtimeViewSlot = null;
}
if (this.runtimeViewFactory) {
this.runtimeViewFactory = null;
}
if (this.runtimeView) {
this.runtimeView = null;
}
this.isApplied = false;
}
private compileView(): void {
this.runtimeViewFactory = createViewFactory(this.viewCompiler, this.container, this.html);
this.runtimeView = createView(this.runtimeViewFactory, this.container);
this.runtimeViewSlot = createViewSlot(this.runtimeViewAnchor);
this.runtimeViewSlot.add(this.runtimeView);
this.runtimeViewSlot.bind(this.bindingContext, this.overrideContext);
this.runtimeViewSlot.attached();
this.isApplied = true;
}
}
function createViewFactory(viewCompiler: ViewCompiler, container: Container, html: string): ViewFactory {
if (!html.startsWith("<template>")) {
html = `<template>${html}</template>`;
}
let viewResources: ViewResources = container.get(ViewResources);
let viewFactory = viewCompiler.compile(html, viewResources);
return viewFactory;
}
function createView(viewFactory: ViewFactory, container: Container): View {
let childContainer = container.createChild();
let view = viewFactory.create(childContainer);
return view;
}
function createViewSlot(containerElement: Element): ViewSlot {
let viewSlot = new ViewSlot(containerElement, true);
return viewSlot;
}
I've created a custom element that generates tabular data. For good reasons, this generates the actual HTML and inserts into the DOM without using a template.
I need to attach click observers to specific elements to I can run a function in the custom element in response to a click. If using a template, I'd use click.delegate, but I can't use that with generated HTML.
How do you attach an event handler with Aurelia other than by using jQuery?
I know this answer is late, but in case this hasn't been (properly) solved yet and/or someone else finds this in the future:
In order to make any aurelia behavior work in dynamically generated HTML, you need to compile that HTML.
I have worked on a custom element (based on how aurelia's enhance and compose work) that allows you to pass in a string of HTML and it will then be compiled, so that any behaviors like bindables, custom elements / attributes will just work. It will also re-compile when the html changes.
Here's an example: https://gist.run?id=1960218b52ba628f73774822aef55ad7
src/app.html
<template>
<dynamic-html html.bind="dynamicHtml"></dynamic-html>
</template>
src/app.ts
export class App {
public dynamicHtml: string = `
<button click.delegate="handleClick()">Click me</button>
`;
public handleClick(): void {
alert("Hello!")
}
}
src/dynamic-html.ts
import {
customElement,
TaskQueue,
bindable,
ViewCompiler,
ViewSlot,
View,
ViewResources,
Container,
ViewFactory,
inlineView,
inject,
DOM
} from "aurelia-framework";
#customElement("dynamic-html")
#inlineView("<template><div></div></template>")
#inject(DOM.Element, TaskQueue, Container, ViewCompiler)
export class DynamicHtml {
#bindable()
public html: string;
public element: HTMLElement;
private tq: TaskQueue;
private container: Container;
private viewCompiler: ViewCompile;
private runtimeView: View;
private runtimeViewSlot: ViewSlot;
private runtimeViewFactory: ViewFactory;
private runtimeViewAnchor: HTMLDivElement;
constructor(element, tq, container, viewCompiler) {
this.element = <HTMLElement>element;
this.tq = tq;
this.container = container;
this.viewCompiler = viewCompiler;
}
public bindingContext: any;
public overrideContext: any;
public bind(bindingContext: any, overrideContext: any): void {
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
if (this.html) {
this.htmlChanged(this.html, undefined);
}
}
public unbind(): void {
this.disposeView();
this.bindingContext = null;
this.overrideContext = null;
}
public needsApply: boolean = false;
public isAttached: boolean = false;
public attached(): void {
this.runtimeViewAnchor = this.element.firstElementChild;
this.isAttached = true;
if (this.needsApply) {
this.needsApply = false;
this.apply();
}
}
public detached(): void {
this.isAttached = false;
this.runtimeViewAnchor = null;
}
private htmlChanged(newValue: string, oldValue: void): void {
if (newValue) {
if (this.isAttached) {
this.tq.queueMicroTask(() => {
this.apply();
});
} else {
this.needsApply = true;
}
} else {
if (this.isApplied) {
this.disposeView();
}
}
}
private isApplied: boolean = false;
private apply(): void {
if (this.isApplied) {
this.disposeView();
}
this.compileView();
}
private disposeView(): void {
if (this.runtimeViewSlot) {
this.runtimeViewSlot.unbind();
this.runtimeViewSlot.detached();
this.runtimeViewSlot.removeAll();
this.runtimeViewSlot = null;
}
if (this.runtimeViewFactory) {
this.runtimeViewFactory = null;
}
if (this.runtimeView) {
this.runtimeView = null;
}
this.isApplied = false;
}
private compileView(): void {
this.runtimeViewFactory = createViewFactory(this.viewCompiler, this.container, this.html);
this.runtimeView = createView(this.runtimeViewFactory, this.container);
this.runtimeViewSlot = createViewSlot(this.runtimeViewAnchor);
this.runtimeViewSlot.add(this.runtimeView);
this.runtimeViewSlot.bind(this.bindingContext, this.overrideContext);
this.runtimeViewSlot.attached();
this.isApplied = true;
}
}
function createViewFactory(viewCompiler: ViewCompiler, container: Container, html: string): ViewFactory {
if (!html.startsWith("<template>")) {
html = `<template>${html}</template>`;
}
let viewResources: ViewResources = container.get(ViewResources);
let viewFactory = viewCompiler.compile(html, viewResources);
return viewFactory;
}
function createView(viewFactory: ViewFactory, container: Container): View {
let childContainer = container.createChild();
let view = viewFactory.create(childContainer);
return view;
}
function createViewSlot(containerElement: Element): ViewSlot {
let viewSlot = new ViewSlot(containerElement, true);
return viewSlot;
}
I have a page that uses a module for defining form content. It is rather generically usable but needs different resulting pages after form actions have been triggered (button click, etc.).
class CreateOrganisationPage extends Page {
static url = "#contact/organisation/create"
static at = {
form.displayed
}
static content = {
form(wait: true) {
module BusinessEntityFormModule, businessEntityName: 'organisation'
}
}
}
The module implementing the form content contains a UI control saveCommand that requires that a page ViewBusinessEntityPage is navigated to after submitting. In order to keep that module more reusable across different tests I wanted to provide that page as a parameter.
What is the best approach to do so?
class BusinessEntityFormModule extends Module {
String businessEntityName = "entity"
String idPrefix = "edit"
static content = {
self {
def id = "$idPrefix-" + StringUtils.capitalize(businessEntityName)
$("form", id: id)
}
saveCommand(to: ViewBusinessEntityPage) {
$('[data-command="save"]')
}
}
}
Simply define a property for the destination page in your module and use it in the content definition:
class BusinessEntityFormModule extends Module {
Class postSavePage
static content = {
saveCommand(to: postSavePage) {
$('[data-command="save"]')
}
}
}
And then set it when defining the module as part of the page:
class CreateOrganisationPage extends Page {
static content = {
form(wait: true) {
module BusinessEntityFormModule, businessEntityName: 'organisation', postSavePage: ViewBusinessEntityPage
}
}
}