Typescript with Ember Views - javascript

I have the following Ember View in Vanilla JS:
App.TextboxView = Ember.View.extend({
tagName: 'div',
classNames: ['custom-text-area__child custom-text-area--text'],
attributeBindings: ['contenteditable'],
isEditable: true,
typing: false,
didInsertElement: function() {
},
contenteditable: (function() {
return this.get('isEditable') ? 'true' : 'false';
}).property('isEditable')
)};
I am attempting to implement said Ember View in Typescript however:
Typescript classes export a function
Ember Views expect an object
contenteditable seems to run due to Embers conventions (somewhere in its lifecycle) and sets the computed property appropriately
How could the contenteditable function be converted to work with Typescript?
So far I have stubbed out the following class:
export class TextboxView {
public tagName = 'div';
public classNames = ['custom-text-area__child custom-text-area--text'];
public atttributeBindings = ['contenteditable'];
public isEditable = true;
public typing = false;
constructor() {
var self = this;
}
}
Is this even possible?

Seems like I am creating a habit of answering my own questions....
The following implementation works as expected (I definitely tried this but obviously was too quick to assume it didn't work LOL):
export class customTextBox {
public tagName = 'div';
public classNames = ['custom-text-area__child custom-text-area--text'];
public attributeBindings = ['contenteditable'];
public isEditable = true;
public typing = false;
public contenteditable = (function () {
return this.get('isEditable') ? 'true' : 'false';
}).property('isEditable')
public keyUp = function(event) {
}
public keyDown = function(event) {
}
}

Related

Angular2 Error: Return type of public method from exported class has or is using private name

I am building out an Angular 2 app using the Angular-CLI, after initially building a working version of the app using the non-CLI version of Angular 2. To my surprise, some code that wasn't a problem in my non-CLI app version HAS been a problem with my Angular-CLI version. All that said, I've resolved everything except for one final error I am stuck on.
This is the error message I'm getting:
Uncaught Error: Module build failed: Error:
/Users/fdr/Documents/rds/rds/cli-rds/src/app/ui/generate-field.component.ts
(340,48): Return type of public method from exported class has or is
using private name 'Hint'.)
And here is the problem file causing the error:
import { Component, Input, Output, EventEmitter, OnInit, AfterViewInit, ElementRef, ViewChild } from '#angular/core';
import { EventHandler } from '../app.event-handler';
import '../app.utils';
#Component({
selector: 'app-generate-field',
templateUrl: 'app/ui/generate-field.component.html',
styleUrls: ['app/ui/generate-field.component.css']
})
export class GenerateField extends EventHandler
{
public get hasFocus(): boolean
{
return this._hasFocus;
}
#Input() delay: number = 300;
#ViewChild('inputField') private inputField: ElementRef;
#ViewChild('suggestionField') private suggestionField: ElementRef;
#Input() public value: string;
#Output() private valueChange: EventEmitter<string> = new EventEmitter<string>();
#Output() public keyup: EventEmitter<KeyboardEvent> = new EventEmitter<KeyboardEvent>();
#Output() public focus = new EventEmitter<KeyboardEvent>();
#Output() public blur = new EventEmitter<KeyboardEvent>();
private inlineSuggestion: string;
private suggestions: ISuggestion[];
#Input() public options: string[];
#Output() private optionsChange: EventEmitter<string[]> = new EventEmitter<string[]>();
private isDirty: boolean = false;
private _hasFocus: boolean = false;
constructor(myElement: ElementRef)
{
super();
this.defineObservableProperty('value');
this.defineObservableProperty('isDirty');
this.defineObservableProperty('suggestions');
this.defineObservableProperty('options');
this.addPropertyListener('isDirty', function ()
{
if (this.isDirty == false)return;
var delay = this.delay ? this.delay : 500;
var self = this;
setTimeout(function ()
{
self.updateSuggestions();
this.isDirty = false;
}.bind(this), delay);
}.bind(this));
this.addPropertyListener('value', (): void=>
{
this.valueChange.emit(this.value);
this.isDirty = true;
});
this.addPropertyListener('suggestions', (): void=>
{
this.updateInlineSuggestion();
});
this.addPropertyListener('options', ()=>
{
this.optionsChange.emit(this.options);
});
}
//--------------------------------------------------------
// Functions
//--------------------------------------------------------
/**
* Evaluates value and updates the list of suggestions
*/
public updateSuggestions(): void
{
// Update suggestions
this.suggestions = this.generateSuggestions(this.value);
}
/***
* Updates the inline suggestion that appears on the text field
*/
private updateInlineSuggestion(): void
{
// Clear inline if there are no suggestions
if (this.suggestions.length == 0)
{
this.inlineSuggestion = '';
return;
}
// Show first option inline
this.inlineSuggestion = this.suggestions[0].value;
var x = this.inputField.nativeElement.selectionStart;
var y = this.inputField.nativeElement.selectionEnd;
this.suggestionField.nativeElement.selectionStart = x;
this.suggestionField.nativeElement.selectionEnd = y;
this.inputField.nativeElement.selectionStart = x;
this.inputField.nativeElement.selectionEnd = y;
this.suggestionField.nativeElement.scrollLeft = x;
}
private onFocus(): void
{
this._hasFocus = true;
// Forward event
this.focus.emit();
}
private onBlur(): void
{
this._hasFocus = false;
// Forward event
this.blur.emit();
}
interface ISuggestion
{
word: string;
match: string;
value: string;
}
try to add "export interface ISuggestion" at the last part of your code so that ISuggestion is exported, too.
Try adding : any after your method. I encountered same problem, It solved after I added any.

AngularJS ng-class doesn't update

I've got a problem with ng-class.
This is a piece of my controller
export class UIController
{
public static $inject = [];
public commands: Array<string> = ['showMap', 'showGantry', 'showSign'];
public showMap: boolean = false;
public showGantry: boolean = false;
public showSign: boolean = false;
public loadingMessage: string;
constructor()
{
this.showMap = true;
}
public toggleContent(commandToExecute: string)
{
for (var command of this.commands) {
if (command != commandToExecute) {
this[command] = false;
}
else if (!this[command]) {
this[command] = true;
}
}
}
}
directive that is connected with it
class LeafletMap implements ng.IDirective
{
public restrict: string = "A";
public controller: string = 'UIController';
public link = (scope, elem, attr) : void =>
{
scope.uiCtrl.loadingMessage = 'test';
scope.$root.$on('details', (event: IAngularEvent, message: any) =>
{
scope.uiCtrl.toggleContent('showGantry');
});
};
}
and piece of HTML view:
<div class="accordion-button" data-ng-click="uiCtrl.toggleContent('showGantry')">Gantry</div>
<div class="accordion-content" data-ng-class="{'show-content':uiCtrl.showGantry}">test</div>
When I call toggleContent method via ng-click, everything works fine then.
But when the call comes from LeafletMap directive it runs toggleContent method and sets proper boolean values to public properties in UIController but ng-class doesn't update.
scope.uiCtrl.loadingMessage = 'test'; //it works correctly BTW
When I run scope.$apply() (just for test) inside LeafletMap after calling toggleContent method, then ng-class was updated, but it caused errors like apply already in progress of course.
Why ng-class doesn't update when I call appropriate controller method within directive?
EDIT
scope.$root.$on('gantry-details', (event: IAngularEvent, message: any) =>
{
this._timeout(() =>
{
scope.uiCtrl.toggleContent('showGantry');
});
});
Using timeout solved the problem.

extending $scope while converting directive to typescript

i want to convert existing directive in javascript to typescript. How do i convert below function
$scope.loadData = function () {
$scope.tableParams = $cspagination.initPromise(getPagedData);
};
So I am trying to write it as
class controller {
this $scope.loadData = (): void {
.....
.....
};
}
but it is giving error that this is not available on class level.
then i tried
class controller {
public $scope.loadData = (): void {
.....
.....
};
}
but this also does not work. its obvious that I cannot define a new public property on $scope, but then atleast I should be able to assign value to it.
so how do I dynamically add functions on $scope?? The workaround I could think of is creating a function extendScope and then
class controller {
public loadData = (): void => {
.....
.....
};
private extendScope = (): void =>{
this.$scope.loadData = this.loaddata;
}
constructor(){
this.extendScope();
}
}
but then this feels like a hack.. are there any cleaner ways of doing this?
The way I go - is to create custom scope definition (i.e. inteface), e.g.:
export interface IMyScope extends ng.IScope
{
loadData: () => void;
otherFunction: function;
...
Ctrl: MyCtrl;
}
and Controller constructor now requires that interface
export class MyCtrl
{
static $inject = ["$scope", ...];
constructor(protected $scope: IMyScope ,
...)
{
this.$scope.Ctrl = this; // we can use "controllerAs" as well
// and here we can add these functions
this.$scope.loadData = this.loadData;
this.$scope.otherFunction = function() {};
...
}
public loadData = (): void => {
//.....
}
See more here:
How To bind data using TypeScript Controller & Angular Js
I don't see anything wrong with this, only that your loadData method shouldn't be public in this case. What I would do though is use the 'controller-as' method:
class controller {
static ID = "myController";
// defining methods like this will make them immediately available on
// the controller with the 'controller as' method
public loadData = (): void => {
//.....
}
constructor(){
}
}
And in your html:
<div ng-controller="myController as $my">
<button ng-click="$my.loadData()">Load!</button>
</div>

Service object wrongly typed for angular directive in Typescript

Below is typescript for an angular directive. The problem is with the injected service "datacontext". The debugger shows that the datacontext in the constructor is a WINDOW object, not the datacontext object that was created as a service. Therefore, in the scope.viewRecord function, the datacontext.cancelChanges() function is, obviously, undefined - - as its not part of a WINDOW object This is probably some strange scoping issue that I just don't get, but I'm at a loss as to how to debug this. Any insight would be most appreciated. Thanks.
module app {
export interface IEditButtonGroup {
...
}
export interface IEditButtonScope extends ng.IScope {
...
}
export class PrxEditButtonGroup implements IEditButtonGroup {
public static $inject: Array<string> = [
"datacontext"
];
constructor(
public datacontext: IDataContext, <---- datacontext HERE is typed as a WINDOW object
public directive: ng.IDirective = {}) {
directive.templateUrl = "app/directives/templates/editbuttongroup.html",
directive.restrict = 'E';
directive.link = (scope: IEditButtonScope, element, attr) => {
scope.isEditing = false;
scope.isAdding = false;
$("form.disabled").find("input:not(:disabled), select:not(:disabled), textarea:not(:disabled)").prop("disabled", true);
scope.editRecord = () => {
$("input, select, textarea").removeAttr("disabled");
scope.isEditing = true;
scope.afterEdit();
}
scope.viewRecord = (afterCancel: boolean) => {
datacontext.cancelChanges(); <--- HERE TOO! Debugger says datacontext = WINDOW object
scope.isEditing = scope.isAdding = false;
$("form.disabled").find("input:not(:disabled), select:not(:disabled), textarea:not(:disabled)").prop("disabled", true);
scope.afterAdd();
}
}
return <any>directive;
}
}
}
The error seems to be at the place where you register this directive. Make sure it is like :
mymodule.directive('prxEditButtonGroup',app.PrxEditButtonGroup )

Writing Javascript for client-side class-level validation using PrimeFaces

I have a class-level Constraint on my class as below:
#NotEqualAccounts
public class FundTransferVO extends SignableVO implements Serializable{
private String fromAccount;
private String toAccount;
//setter,getter
}
and my custom Constraint code is:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = NotEqualAccountsValidator.class)
#ClientConstraint(resolvedBy=ClientNotEqualAccountsValidator.class)
public #interface NotEqualAccounts {
String message() default "{org.javaee7.validation.custom.constraint.NotEqualAccounts}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
I want to have a javaScript for client-side validation of my class using primeFace, I've already written the code below, but it doesn't work
PrimeFaces.validator['NotEqualAccounts'] = {
MESSAGE_ID: '...',
validate: function(element, fundTransferController) {
if(fundTransferController.fundTransferVO.getToAccount()===fundTransferController.fundTransferVO.getFromAccount()) {
msg = '';
throw msg;
}
}
};
fundTransferController is just my controller that my bean(fundTransferVO) is used in it.
Is there a way to validate class-level constraints on client-side using primeFace?

Categories

Resources