Is there any way in ActionScript3 to get enum from string value?
e.g. I have enum
public final class Day
{
public static const MONDAY:Day = new Day();
public static const TUESDAY:Day = new Day();
public static const WEDNESDAY:Day = new Day();
public static const THURSDAY:Day = new Day();
public static const FRIDAY:Day = new Day();
public static const SATURDAY:Day = new Day();
public static const SUNDAY:Day = new Day();
}
and I want to get enum Day.MONDAY from string "MONDAY"
In ActionScript obj.prop is same as obj["prop"] - just confirmed that this applies to static properties too. So you can access it like:
trace(Day["MONDAY"]);
or
var day:String="MONDAY";
trace(Day[day]);
Just to quickly chime in on this for future reference; if you have access to modify the class, a fromString(); method would be preferable as it makes the API clearer for other developers.
public static function fromString(value : String) : Day
{
switch(value.toLowerCase())
{
case "monday":
return MONDAY;
case "tuesday":
return TUESDAY;
// ...etc
default:
throw new ArgumentError(value + " is not a valid value");
return null;
}
}
Related
I have a base class on baseviewmodel.
I'm facing navigationservice implemented on 6.2 on debug shows problem navigating to another viewmodel.
debug shows userdialogs break.
Is there a problem using base class in this way with those parameters . anyone faced this kind of issue
public BaseViewModel(IMvxNavigationService navigationService,
ILoginService loginService,
UserDialogs userDialogs, IValidator validator) {
_navigationService = navigationService;
_loginService = loginService;
_userDialogs = userDialogs;
_validator = validator;
Title = TextSource.GetText(StringResourceKeys.Title);
IsBusyMessage = Resources.Strings.LoadingMesssage;
}
using gettext provider like this
public class ResourcexTextProvider : IMvxTextProvider
{
private readonly ResourceManager _resourceManager;
public ResourcexTextProvider(ResourceManager resourceManager)
{
_resourceManager = resourceManager;
CurrentLanguage = CultureInfo.CurrentUICulture;
}
public CultureInfo CurrentLanguage { get; set; }
public string GetText(string namespaceKey, string typeKey, string name)
{
string resolvedKey = name;
if (!string.IsNullOrEmpty(typeKey))
{
resolvedKey = $"{typeKey}.{resolvedKey}";
}
if (!string.IsNullOrEmpty(namespaceKey))
{
resolvedKey = $"{namespaceKey}.{resolvedKey}";
}
return _resourceManager.GetString(resolvedKey, CurrentLanguage);
}
public string GetText(string namespaceKey, string typeKey, string name, params object[] formatArgs)
{
string baseText = GetText(namespaceKey, typeKey, name);
if (string.IsNullOrEmpty(baseText))
{
return baseText;
}
return string.Format(baseText, formatArgs);
}
public bool TryGetText(out string textValue, string namespaceKey, string typeKey, string name)
{
throw new System.NotImplementedException();
}
public bool TryGetText(out string textValue, string namespaceKey, string typeKey, string name, params object[] formatArgs)
{
throw new System.NotImplementedException();
}
}
}
You're trying to inject UserDialogs userDialogs in the ctor of your BaseViewModel. My guess is that you missed registering the userDialogs.
First of all you should inject interfaces instead of implementations to improve maintainability:
Mvx.IocConstruct.RegisterType<IUserDialogs, UserDialogs>();
And if my guess is correct and you are using Acr.UserDialogs you should initialize it and register it as:
Mvx.IoCProvider.RegisterSingleton<IUserDialogs>(() => UserDialogs.Instance);
Then you can inject it in any ViewModel directly using the interface:
public BaseViewModel(IMvxNavigationService navigationService,
ILoginService loginService,
IUserDialogs userDialogs,
IValidator validator) {
_navigationService = navigationService;
_loginService = loginService;
_userDialogs = userDialogs;
_validator = validator;
Title = TextSource.GetText(StringResourceKeys.Title);
IsBusyMessage = Resources.Strings.LoadingMesssage;
}
HIH
I need to create some enum values, give it a default value and then compare it.
I have this enum class
public class Car
{
public static const Tesla:int = 1;
public static const Ford:int = 2;
}
How do I initiate a new Car enumn variable with a default value of "Tesla" and how do I compare the variable? I'm looking for something like this:
public var c:Car = new Car(Car.Tesla);
if (c == Car.Tesla){
// Do something
}
Edit, it is now changed to the following:
public final class Car
{
public static const Tesla:String = "tesla";
public static const Ford:String = "ford";
}
And in the mxml file:
public var c:String = Car.Tesla;
if (c == Car.Tesla){
// Do something
}
I have this enum class
Just so we're on the same page about it: that's not an enum and there are no enums in as3. The language doesn't have that feature.
How do I initiate a new Car enumn variable with a default value of "Tesla" and how do I compare the variable?
You cannot, because Car is a type and the static properties it has are of type int which is something completely different.
What you can do is this:
var c:int = Car.Tesla;
if (c == Car.Tesla){
// Do something
}
If you want to have a Car object instead, add a brand property to the class of type int, which you can then assign the value of your constants to:
var c:Car = new Car();
c.brand = Car.Tesla;
if (c.brand == Car.Tesla){
// Do something
}
You could also add a parameter to the constructor and insert the value there.
Btw. changing
public static const Tesla:int = 1;
to
public static const Tesla:String = "tesla";
will give you the chance to get more meaningful values during debugging. The built in constants like MouseEvent.CLICK are defined this way.
How does MVC 6 renders a view. What's the actual method in Razor ViewEngine that generates the html output? Also if possible please explain the process of rendering a view.
May be you could point me to a file on mvc source on github. thanks!
Here is a complete solution of what you are looking for. I used dependency injection to get the HtmlHelper in the controller. You can inject your own helper if you want too.
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.WebEncoders;
using System.ComponentModel.DataAnnotations;
using System;
public class MyController : Controller
{
private readonly IHtmlGenerator htmlGenerator;
ICompositeViewEngine viewEngine;
IModelMetadataProvider metadataProvider;
private readonly IHtmlHelper helper;
IHtmlEncoder htmlEncoder;
IUrlEncoder urlEncoder;
IJavaScriptStringEncoder javaScriptStringEncoder;
public MyController(IHtmlHelper helper, IHtmlGenerator htmlGenerator, ICompositeViewEngine viewEngine, IModelMetadataProvider metadataProvider, IHtmlEncoder htmlEncoder, IUrlEncoder urlEncoder, IJavaScriptStringEncoder javaScriptStringEncoder)
{
this.htmlGenerator = htmlGenerator;
this.viewEngine = viewEngine;
this.metadataProvider = metadataProvider;
this.htmlEncoder = htmlEncoder;
this.urlEncoder = urlEncoder;
this.javaScriptStringEncoder = javaScriptStringEncoder;
this.helper = helper;
}
[HttpGet]
public IActionResult MyHtmlGenerator()
{
MyViewModel temp = new MyViewModel();
var options = new HtmlHelperOptions();
options.ClientValidationEnabled = true;
ViewDataDictionary<MyViewModel> dic = new ViewDataDictionary<MyViewModel>(this.metadataProvider, new ModelStateDictionary());
ViewContext cc = new ViewContext(ActionContext, new FakeView(), dic, TempData, TextWriter.Null, options);
var type = typeof(MyViewModel);
var metadata = this.metadataProvider.GetMetadataForType(type);
ModelExplorer modelEx = new ModelExplorer(this.metadataProvider, metadata, temp);
ViewData["Description"] = "test desc";
ViewData["Id"] = 1;
this.ViewData = new ViewDataDictionary(this.metadataProvider, new ModelStateDictionary());
IHtmlHelper<MyViewModel> dd = new HtmlHelper<MyViewModel>(this.htmlGenerator, this.viewEngine, this.metadataProvider, this.htmlEncoder, this.urlEncoder, this.javaScriptStringEncoder);
((ICanHasViewContext)dd).Contextualize(cc);
dd.ViewContext.ViewData = this.ViewData;
var desc = GetString(dd.TextBoxFor(m => m.ID));
var ID = GetString(dd.TextBoxFor(m => m.Description));
// Do whatever you want with the ID and desc
return new ContentResult() { Content = ID + desc };
}
public static string GetString(IHtmlContent content)
{
var writer = new System.IO.StringWriter();
content.WriteTo(writer, new HtmlEncoder());
return writer.ToString();
}
}
public class MyViewModel : BaseAssetViewModel
{
// [RegularExpression(#"^-?\d{1,13}(\.\d{0,5})?$|^-?\.\d{1,5}$")]
[Required]
public int ID { get; set; }
[MinLength(2)]
public string Description { get; set; }
// Property with no validation
public string Other { get; set; }
}
public class FakeView : IView
{
string IView.Path
{
get
{
throw new NotImplementedException();
}
}
public Task RenderAsync(ViewContext viewContext)
{
throw new InvalidOperationException();
}
Task IView.RenderAsync(ViewContext context)
{
throw new NotImplementedException();
}
}
I don't know if this may be of help, may be you have to start to look at tag helpers:
https://github.com/DamianEdwards/TagHelperStarterWeb
they're working to a different way to create helpers that integrate in the page in a more natural way.
I think Im having a really noob moment, Im returning a remote object from coldfusion and I want to specify the object type. i.e Im getting an worker from coldfusion and I have a Value object Worker.
Heres what I have been trying
public function ResultHandler_GetWorker(event:ResultEvent):void
{
var result:ArrayCollection = ArrayCollection(event.result);
var worker:WorkerVO = WorkerVO(result[0]);
model.worker = worker;
}
Result[0] is an employee object. Its structure from debug looks like this.
workerAddress "24b fake Ave"
workerCity "Wellton"
workerCountry "Ameriland"
workerEmail "Afake#me.com"
workerFName "Foo"
workerHPhone "435234"
workerID 1
workerImage null
workerIsAdmin true
workerLName "Foo"
workerMPhone "827271903"
workerPassword "password"
workerPosition "Leader"
workerState ""
workerSuburb "Birkenhead"
workerWPhone null
my class looks like this:
public class WorkerVO
{
public var _workerAddress:String
public var _workerCity:String
public var _workerCountry:String
public var _workerEmail:String
public var _workerFName:String
public var _workerHPhone:String
public var _workerID:uint;
public var _workerImage:String
public var _workerIsAdmin:Number;
public var _workerLName:String
public var _workerMPhone:String;
public var _workerPassword:String;
public var _workerPosition:String;
public var _workerState:String;
public var _workerSuburb:String;
public var _workerWPhone:String;
public function WorkerVO()
{
}
//Getters & Setters
}
Error #1034: Type Coercion failed: cannot convert Object#114eeb251 to com.cavej03.sitesafe.vo.WorkerVO.
Am I doing it completely wrong. Am I simply meant to make a function or constructor that accepts this object and maps its fields to a new WorkerVO
You're missing a RemoteClass metadata tag. This tag tells your application which server-side VO a given client-side VO is mapped to.
Use it like this:
[RemoteClass(alias="path.to.WorkerVO")] //this is the servers-side path
public class WorkerVO {
...
}
Furthermore from what you're showing it looks like the names of your properties don't match: the client-side one has prepended underscores while the server-side one doesn't.
The property names of the client-side VO and the server-side one should be exactly the same. For instance:
/* Java VO */
public class WorkerVO {
private String workerAddress;
public String getWorkerAddress() {
return workerAddress;
}
public void setWorkerAddress(String workerAddress) {
this.workerAddress = workerAddress;
}
}
/* ActionScript VO */
[RemoteClass(alias="path.to.WorkerVO")]
public class WorkerVO {
public var workerAddress:String;
}
This is an example with a Java VO, but the same applies to ColdFusion.
Assign the returned object to a property within WorkerVO, and prepare getters for each of them like so:
public class WorkerVO
{
private var _base:Object;
public function WorkerVO(base:Object)
{
_base = base;
}
public function get address():String{ return _base.workerAddress; }
public function get city():String{ return _base.workerCity; }
// Etc.
}
And the definition of a worker just needs the new keyword added:
var worker:WorkerVO = new WorkerVO(result[0]);
trace(worker.address);
i'd like to throw an argument error if a particular function doesn't work without a passed value that also happens to be a public constant of the class containing the function.
is there anyway to determine if a class owns a public constant instead of having to iterate thru all of them?
something like this:
public static const HALIFAX:String = "halifax";
public static const MONTREAL:String = "montreal";
public static const TORONTO:String = "toronto";
private var cityProperty:String;
public function set city(value:String):void
{
if (!this.hasConstant(value))
throw new ArgumentError("set city value is not applicable.");
cityProperty = value;
}
public function get city():Strig
{
return cityProperty;
}
currently, for this functionality i have to write the city setter function like this:
public function set city(value:String):void
{
if (value != HALIFAX && value != MONTREAL && value != TORONTO)
throw new ArgumentError("set city value is not applicable.");
cityProperty = value;
}
is this the only way to accomplish this task?
Yes, if you use reflections:
private var type:Class;
private var description:XML;
private function hasConstant (str : String ) : Boolean
{
if (description == null)
{
type = getDefinitionByName (getQualifiedClassName (this)) as Class;
description = describeType (type);
}
for each ( var constant:XML in description.constant)
{
if (type[constant.#name] == str) return true;
}
return false;
}
Note that for this to work, all constants must always be String objects declared public static const.
I was looking for an answer to this question myself and found it annoying that hasOwnProperty() did not work for static properties. Turns out though, that if you cast your class to a Class object, it does work.
Here's an example:
public final class DisplayMode
{
public static const one: String = "one";
public static const two: String = "two";
public static const three: String = "three";
public static function isValid(aDisplayMode: String): Boolean {
return Class(DisplayMode).hasOwnProperty(aDisplayMode);
}
}
I owe this solution to jimmy5804 from this discussion, so hats off to him.
You should be able to use bracket notation to do this. For example:
var foo:Sprite = new Sprite();
foo.rotation = 20;
trace( foo["x"], foo["rotation"]); // traces "0 20"
or more specific to your case:
var bar:String = "rotation";
trace( foo[bar] ); // traces "20"
The only thing you have to look out for here, is that the bracket accessor will throw a ReferenceError if you ask for an object property that isn't there, such as:
trace ( foo["cat"] ); // throws ReferenceError
But it will not throw if you are asking for a static property:
trace ( Sprite["cat"] ); // traces "undefined"
So in your case you might try:
if ( this[value] == undefined ) {
throw new ArgumentError("set city value is not applicable.");
}
EDIT:
Sorry, I was confusing the const's names with their values.
For this to work on your problem you would have to make the String value the same as the const's name, so for example:
public static const HALIFAX:String = "HALIFAX";
then you could use the query as described above and it would give you the desired result.