Access HTML element from Glimmer component without modifier - ember.js

is it possible to access component's HTML element in Glimmer components without the use of did-insert helper? Something as simple as this.element or this.elementId in non-glimmer elements.
I've created a class that extends Component that all my components will be extending. After my "special" component is created I want to manipulate with its DOM.

No. Glimmer Components introduced as part of Ember Octane does not provide direct access to DOM. Instead modifiers were introduced for features that require DOM manipulation.
Modifiers provide access to the element on which they are used and are meant to manipulate the DOM. This provides a better reuse as they can be used in any template and aren't coupled with a specific component.
Your "special" component might be better implemented as a modifier.
{{did-insert}} is very likely not a helper but a modifier provided by #ember/render-modifiers package. For most cases it's better to implement a custom modifier than using generic modifiers like {{did-insert}}. These modifiers are a great transition helper to refactor existing code but still coupling the element modification to a specific class.
ember-modifier package provides a nice API to implement modifiers either with a functional or a class-based approach. You don't need to care about the low-level APIs provided by modifier manager.

Related

Sharing non-layout templates between apps using Meteor

I have two meteor apps. Each one has a smart-package that implements a certain feature, lets say user management, in an app-specific way. I also have a third meteor smart package that lives in a shared package directory. This third package has user management templates that are common to both apps. I use iron-router.
I need to combine the shared templates with the app templates. Iron-Router has the yield keyword. This is useful for combining templates. The problem is that this only works for special, nominated layout templates.
How do you combine, or nest, templates that are not layout templates using meteor and iron-router?
Example
In the simplified example below you can see three packages and their corresponding templates. The app-*:user packages implement app specific user templates and the shared:user package implements a shared user template.
app-1:users
appUser.tpl.jade
p This is some App-1 specific text
app-2:users
appUser.tpl.jade
p This is some App-2 specific text
shared:users
user.tpl.jade
h1 This is a shared title
+appUser
routes.coffee
Router.route '/user', name: 'user'
The problem here is that the nested template must be called appUser in both the dependent smart packages. This not only prevents the templates name being appropriately descriptive for the app but, more worryingly, tightly couples the template name and makes for fragile code.
It is to prevent this tight coupling of templates that iron-router allows us to use the yield keyword, but since we cannot use the yield keyword in this context (can we?) then I am left wondering if this truly is the only way to implement shared templates?
You're probably going to benefit from dynamic templates. These are templates whose name can be passed in via a helper (defined globally or tied to the parent template) and whose data context can even be set by a helper.
{{> Template.dynamic template=myTemplate [data=myData] }}
Your code supplies myTemplate and myData dynamically here and the kerbobble (html, helpers, event handlers) then gets stuffed into the parent template.

Qtilities: Custom property types for the property browsers?

I'm writing a program that requires the user to be very flexible in manipulating data on a given object. I figured I would use a property browser of some kind; Qtilities' ObjectDynamicPropertyBrowser caught my eye.
However, I need to be able to add my own data types. The documentation is not clear on how to do so.
How can I allow my own data types to be represented in Qtilities' property browser widgets?
Also, more about my needs:
The data types are not part of Qt, nor are they even Q_OBJECTs.
Qt-specific modifications to the relevant classes are not an option.
Declaring the relevant classes via Q_DECLARE_METATYPE is okay.
In particular, I need to represent vector and matrix types (and possibly more later).
The browser you refer to depends on the QObject property system. So, unless your classes are QObjects, it won't work - but don't despair, Qt 5.5 to the rescue (read on). The browser seems to use a QTreeView and provides an adapter model that exposes the QObject property system. So, it leverages Qt's type and delegate system.
In Qt 5.5, there is a general purpose property system, known as gadgets, that can be used on any class, as long as there is a QMetaObject describing that class. By adding the Q_GADGET macro to a class deriving from the subject class, and describing the properties using Q_PROPERTY macro, you can leverage moc and the gadget system to access your unmodified types' properties.
The only reason you'd do that is to require minimal changes to the ObjectPropertyBrowser system. You don't want the ObjectDynamicPropertyBrowser, since it works on dynamic properties, and your objects don't have any. They have static properties, given through Q_PROPERTY macros and code generated by moc.
So, you'll proceed as you would for implementing your own type support for QVariant and views in general. You also need Qt 5.5, since you need gadget support for it to work. A solution for Qt 5.4 and below requires a different approach and might be less cumbersome to implement in another way.
See this answer for a reference on using gadget property system for object serialization, it's fundamentally what the property browser would do, sans the serialization proper of course.
There are three steps. First, you need to address simple custom types that don't have a structure, but represent a single value (such as a date, or time, or geographic position, etc.), or a collection of simple values (such as a matrix).
Ensure that QVariant can carry the simple types. Add the Q_DECLARE_METATYPE macro right after the type's definition in an interface (header file).
Implement delegates for the types. For types with table structure, such as a matrix, you can leverage QTableView and provide an adaptor model that exposes the type's contents as a table model.
Secondly, you get to your complex types that have internal structure:
Create a wrapper class that derives from the complex type, declares all properties using Q_PROPERTY, and has the Q_GADGET macro (not Q_OBJECT since they are not QObjects). Such class should not have any members of its own. Its only methods should be optional property accessors. The Q_GADGET macro adds the static (class) member staticMetaObject.
The underlying type can be static_cast to the wrapper class if needed, but that's normally not necessary.
At this point, any class that you wrote a wrapper for is accessible to the QMetaProperty system directly, without casting! You'd use the wrapper's staticMetaObject for its static metaobject, but the QMetaProperty readOnGadget and writeOnGadget will take the pointers to the base class directly.
Thirdly, since ObjectPropertyBrowser most likely doesn't implement the support for gadgets in Qt 5.5, as that's quite new, you'll have to modify it to provide such support. The changes will be minimal and have to do with using QMetaProperty::readOnGadget and QMetaProperty::writeOnGadget instead of QMetaProperty::read and QMetaProperty::write. See the serialization answer for comparison between the two.

Best practices with Ember ArrayProxy

Ember's Em.ArrayProxy and Em.Array have many programatic methods available for notifying observers of changes to content. For example:
arrayContentDidChange
arrayContentWillChange
enumerableContentDidChange
enumerableContentWillChange
contentArrayWillChange
Em.ArrayProxy also has several methods for manipulating the ArrayProxy's content. For example:
this.pushObject('something random');
// Or
this.insertAt(2, 'something random');
When using the latter methods, does one have to use them in conjunction with the former methods? It seems silly that Ember's usually-automated property observers would require a manual kick here but I don't find the documentation very clear.
No, you don't have to use any methods in conjunction.
If you want to add items to your ArrayProxy, simply pushObject(). You would know this by just using the method and seeing that it just works.
From the docs:
This mixin implements Observer-friendly Array-like behavior. It is not a concrete implementation, but it can be used up by other classes that want to appear like arrays.
http://emberjs.com/api/classes/Ember.Array.html
Ember.Array is a type of class that in other programming languages (without mixins) receives the name of an interface.
An ArrayProxy wraps any other object that implements Ember.Array
http://emberjs.com/api/classes/Ember.ArrayProxy.html
Ember.ArrayProxy is exactly what the name says, a proxy, that wraps around any object that has implemented the Ember.Array interface.
The other methods, that you mention, might be implemented/overridden if you are making your own "subclass" of Ember.Array. Some must be implement to make your subclass ArrayProxy friendly. Or if you want to add custom behaviour, maybe write to a log whenever arrayContentDidChange, then you override that method and add whatever logic your app needs.
That is Object Oriented Programming and all those explanations are out of scope for the documentation of any framework.
Are you asking whether pushObject et cetera trigger those events?
From the documentation for insertAt:
This will use the primitive replace() method to insert an object at the specified index.
From the documentation for replace:
You should also call this.enumerableContentDidChange()
So, yes, a properly implemented ArrayProxy will trigger those events when you add or remove things.

Famo.us: different ways of creating and calling functions

Hoping someone can provide an explain-like-I’m-five elucidation of the difference between the following types of functions within Famo.us, and when it’s appropriate to use them:
sampleFunction() {}
_sampleFunction() {}
SampleView.prototype.sampleFunction() {}
.bind and .call are also thrown around a lot…I understand them vaguely but not as concretely as I’d like. That might be a different question, but please feel free to use them in your explanation!
Apologies for the vagueness...wish there was more regarding this in famo.us university.
None of what you're looking at is syntax specific to Famo.us. It's actually common, if intermediate level, VanillaJS.
The _ is simply a coding convention to denote that a specific function should belong to the parent scope (ie a member/private function, whatever you prefer to call it). Javascript doesn't really have support for encapsulation - the act of blocking other classes and objects from accessing another class's functions and variables. While it is possible, it's quite cumbersome and hacky.
You'll see that Famo.us uses the underscore convention to denote that a function is a member of the class using it. Some of these functions are actually just aliases to the actual Javascript native function, for example ._add actually just call's Javascript's .add method. Of course, ._add could be updated in the future on Famo.us's end to do more in the future if that's required. You really wouldn't want to try and write over the native Javascript add. That's super bad.
The other upshot is that you can document that class and say that you can and should use the _add method for a specific purpose/scenario. You'll see that in the API docs.
Understanding prototype is a core part of what it means to be a Javascript Programmer, after all, it is a prototype driven language. MDN has a much better explanation than anything I can offer here but it's basically at the core of your classes.
If you want to extend off of an existing class (say, create your own View or Surface type) you would extend it's prototype. Check out Famous Starter Kit's App examples and see how many of them create an "AppView" class, which takes the prototype of the core View, copies it for itself, and then adds it's own functions, thus extending View without ruining the original copy.

Consuming custom objects between webservices

I have a webservice that is designed to accept performance data via a custom object. The custom object contains a Collection (Generic List) of performance measures among other data. The performance measure consists of simple data types (strings, ints, and a datetime). The only method exposed by the webservice requires this custom object (performance data object) to be passed in.
The problem lies in using this custom object externally. I wish to use the Add() and Item() methods of the Generic List class along with various other features within this class within another webservice. If I request the object from the Performance Data Webservice it seralizes the inner collection to an arrayList. I would like it to remain a generic collection.
I have toyed with using the XmlInclude method but currently havent found a solution with it.
The next thing I tried to do was create an assembly of this specific object that both the Peformance Data web service can use and any satelite programs (i.e. another webservice). The issue here is when I try to pass in the custom object created by the seperate assembly the performance data webservice barks its a different type. (Also I am applying the XmlInclude(GetType( custom assembly)) attribute to the exposed method). However still thinks the types are not convertable.
Note: I would prefer to call the Performance Data WS to get the custom object instead of having to deal with adding assemblies to each project that needs access.
Anyone have an idea other than restructing the program to work with methods exposed by the ArrayList?
If you use WCF, you can configure what type of collection comes out, whether an ArrayList, a fixed array, or a generic List.
I have found a solution that will work with .Net 2.0. By using Web Services Contract First (WSCF http://www.thinktecture.com/resourcearchive/tools-and-software/wscf/wscf-walkthrough)
I was able to pass generic collections between two services. A down side to WSCF, as the name suggests, is the approach requires the use of contract-first instead of the more common code-first methodology. Lucky it is not terribly complicated to modify the class and proxy after they are created. Hope this helps any lost travelers...