2015-07-05 14 views
9

Ich spiele nur mit der benutzerdefinierten Elementfunktionalität in Aurelia und versuchte, ein "Fortschrittsbalken" -Element zu erstellen.Aurelia: Zugreifen auf Custom Element benutzerdefinierte Funktionen oder benutzerdefinierte Attribute

Progress-bar.js

import {customElement, bindable} from 'aurelia-framework'; 
@customElement('progress-bar') 
export class ProgressBar 
{ 
//do stuff// 
} 

Progress-bar.html

<template> 
    <link rel="stylesheet" type="text/css" href="src/components/progress-bar.css"> 
    <div class='progress-bar' tabindex=0 ref="bar">bloo</div> 
</template> 

test.html (relevanten Teil)

<require from="./components/progress-bar"></require> 
    <progress-bar ref="pb">a</progress-bar> 

All dies zeigt sich in Ordnung. Aber ich kämpfe darum, wie man die Hauptseite aufrufen kann, um eine Funktion aufzurufen oder ein Attribut für ein Element zu ändern, das dann etwas auf dem Fortschrittsbalken selbst machen sollte.

Ich habe versucht, eine Funktion 'doSomething' in der progress-bar.js zu erstellen, aber ich kann nicht in test.js zugreifen.

hinzugefügt, um die Fortschritte-bar.js

doSomething(percent, value) { 
    $(this.bar).animate('width: ${percent}%', speed); 
} 

innen test.js

clicked() { 
    console.log(this.pb); // this returns the progress bar element fine 
    console.log(this.pb.doSomething); //this returns as undefined 
    this.pb.doSomething(percent, value); // this fails outright with error: typeError - doSomething is not a function 
} 

Next I Setup benutzerdefinierte versucht Attribute innerhalb Fortschritt-Stabelement und vielleicht Valuechange verwenden, um die div stattdessen zu ändern .

Innen Fortschritt-bar.js

@bindable percent=null; 
@bindable speed=null; 

test.js

clicked() { 
this.pb.percent=50; //this updated fine 
this.pb.speed=1500; //this updated fine 

} 

Kein Problem da, fast da. Aber wie richte ich einen Handler ein, der aufgerufen werden soll, wenn sich ein Attribut ändert?

fand ich ein Tutorial, das diese Syntax hatte:

@bindable({ 
    name:'myProperty', //name of the property on the class 
    attribute:'my-property', //name of the attribute in HTML 
    changeHandler:'myPropertyChanged', //name of the method to invoke on property changes 
    defaultBindingMode: ONE_WAY, //default binding mode used with the .bind command 
    defaultValue: undefined //default value of the property, if not bound or set in HTML 
}) 

Aber ich kann nicht, dass Code in meinem Fortschritt-bar.js zu verwenden scheinen. Die Seite nicht richtig zu machen, nachdem ich hinzufügen, dass in Gulp scheint keine Fehlermeldungen zurückgegeben zu haben, aber die Browser-Konsole gibt diesen Fehler zurück.

ERROR [app-router] Router navigation failed, and no previous location could be restored.

, die die Nachricht, die ich normalerweise, wenn ich habe irgendwo auf meinen Seiten einen Syntaxfehler.

Es gibt viele Dinge, die ich bin nicht sicher, hier:

Ist dies die richtige Verwendung für benutzerdefinierte Elemente? Können wir benutzerdefinierte Elemente mit Funktionen in ihnen erstellen? Können wir benutzerdefinierte Elemente mit benutzerdefinierten Attributen erstellen, die dann Ereignisse auslösen können, wenn sich ihre Werte ändern?

Entschuldigung dafür, dass ich keine ganzen Codes gepostet habe, da ich so viele Variationen davon habe, während ich verschiedene Dinge ausprobiere.

+0

Ich fand es heraus. this.pb verweist auf das Element progress-bar. Darin befindet sich ein progressBar-Objekt der Klasse ProgressBar. Um also auf Funktionen innerhalb der benutzerdefinierten Elementklasse zuzugreifen, muss die this.pb.progressBar und die Attribute identisch sein. –

+0

Wenn Sie Ihr Problem beantwortet haben, können Sie Ihre tatsächliche Lösung posten und dann als Antwort markieren? – Andrew

Antwort

15

Mit Aurelia, können Sie diese Konvention in Ihrer Komponente verwenden: yourpropertynameChanged()

import {customElement, bindable, inject} from 'aurelia-framework'; 
import $ from 'jquery'; 

@customElement('progress-bar') 
@inject(Element) 
export class ProgressBar 
{ 
    @bindable percent; 
    @bindable speed; 

    constructor(element){ 
     this.element = element; 
    } 

    percentChanged(){ 
     doSomething(this.percent, this.speed); 
    } 

    speedChanged(){ 
     doSomething(this.percent, this.speed); 
    } 

    doSomething(percent, value) { 
     $(this.element).animate('width: ${percent}%', value); 
    } 
} 

Sie brauchen nicht von outsite zum doSomething() zuzugreifen.
Aber Sie müssen nur die Eigenschaften ändern:

<progress-bar percent="${pb.percent}" speed="${pb.speed}">a</progress-bar> 
+0

Danke, das ist eine Art, mit der ich endete. –

4

ich einen einfache faulen Ansatz genommen habe und nprogress ist verwenden, können Sie nprogress.set(0.4) verwenden, aber ich bin mit dem Standard „etwas geschieht“ Verhalten .

import nprogress from 'nprogress'; 
import {bindable, noView} from 'aurelia-framework'; 

@noView 
export class LoadingIndicator { 
    @bindable loading = false; 

    loadingChanged(newValue){ 
    newValue ? 
     nprogress.start() : 
     nprogress.done(); 
    } 
} 
0

Zuerst bindet einige Objekte zu Ihrem benutzerdefinierten Elemente, zum Beispiel "config":

<custom-element config.bind="elementConfig"></custom-element> 

dann in Ihrer Seite js-Datei:

someFunction(){ this.elementConfig.elementFunction(); } 

und in Ihrem benutzerdefiniertes Element hinzufügen ein Funktion wie folgt:

@bindable({ name: 'config', attribute: 'config', defaultBindingMode: bindingMode.twoWay }); 
export class JbGrid { 
    attached() { 
     this.config.elementFunction = e=> this.calculateSizes(); 
    } 
    calculateSizes() { 
    //your function you want to call 
    } 
} 

Jetzt haben Sie Zugriff auf das benutzerdefinierte Element "this" in Ihrer Funktion.