ChaplinJS: Referencing a CollectionView property in its template - chaplinjs

I have a Collection in ChaplinJS that has the following initialization code:
Chaplin = require 'chaplin'
Collection = require 'models/base/collection'
Domain = require 'models/domain'
mediator = require 'mediator'
module.exports = class Domains extends Collection
model: Domain
# Initialize the SyncMachine
_(#prototype).extend Chaplin.SyncMachine
initialize: ->
super
#.totalHits = 0
How can I reference totalHits in the template of its view? I am using handlebars templates, and writing {{totalHits}} returns nothing.
Incidentally, shouldn't I be able to rewrite the above code with:
module.exports = class Domains extends Collection
model: Domain
totalHits: 0

Found the solution:
In my CollectionView I can override getTemplateData and pass into it whatever I want, including the complete collection object:
getTemplateData: ->
templateData = super
templateData.collection = #.collection
templateData
Then in the handlebars template I can do {{collection.totalHits}}

Related

Is there a way to pass extra parameters to Handsontable validator functions?

I am using Handsontable v0.35.1 which is the latest version at the time of posting this question. It is used as part of Angular 5 (Typescript) component and view.
For each cell in table, I attach a custom validator as per guidelines in official documentation . Code looks something like this:
class ValidationService {
static myCustomColumnAValidator(value, callback) {
var contextObject = this;
//... validation logic
}
static myCustomColumnBValidator(value, callback) {
var contextObject = this;
//... validation logic
}
}
var hot = new Handsontable(document.getElementById('myTableContainer'), {
data: [ { 'ColumnA': 'Data'}, { 'ColumbB' : 'Data' } }],
columns: [
{
data: 'ColumnA',
validator: ValidationService.myCustomColumnAValidator
},
{
data: 'ColumnA',
validator: ValidationService.myCustomColumnBValidator
}
]
});
Question is, can I pass some extra parameters to the custom validator functions (myCustomColumnAValidator and myCustomColumnBValidator) apart from the value and callback function reference? I need some extra parameters as part of validation logic.
Also note that I had to mark the custom validator functions in ValidationService as static because the context object this is overridden to be the ColumnSettings object when Handsontable calls the validation function. If this was not the case, I could initialize the ValidationService with some member variables via its constructor and use in non-static version of the same validation function using this which would refer to the ValidationService instance. But this does not seem to be possible because Handsontable overrides the "this" context object, which I can see by stepping through the Handsontable code which uses ValidationFunction.call(contextObject, value, callback) mechanism.
Any pointers will be greatly appreciated. Thanks!
Pass whatever you want here
columns: [
{
data: 'ColumnA',
validator: ValidationService.myCustomColumnAValidator,
customParameter: 10
}
]
And you can access it like so this.customParameter in the validator.

Provide new instances of model class for dependency injection in Angular 2

I have a class that serves as a model for some data I get from a server. This data starts as an unwieldy xml object where text nodes have attributes so the json format I convert it into does not have simple string values. Instead I have:
#Injectable()
export class FooString {
_attr: string;
value: string;
isReadOnly(): boolean {
return this._attr && this._attr === 'ReadOnly';
}
isHidden(): boolean {
return this._attr && this._attr === 'Hid';
}
}
Then my model is like:
#Injectable()
export class Payment {
constructor(
public FooId: FooString,
public FooStat: FooString,
public FooName: FooString ) { }
}
Everything ends up with the same instance of FooString. How do I get discrete instances for each of them?
I have tried a factory, but it still only creates a single instance:
export let fooStringProvider = provide(FooString, {
useFactory: (): FooString => {
console.log('in foostring factory');
return new FooString();
}
});
new FooString();
new Payment();
;-)
Why using DI when they don't have dependencies and you don't want to maintain single instances per provider. Therefore, just use new.
When to use DI
There are a few criterias when using DI instead of new the right thing:
If you want Angular to maintain and share instances
If you want to work with an interface or base class but then you want to configure from the outside what implementation should actually be used at runtime - like the MockBackend for Http during testing.
If you class has dependencies to instances and/or values provided by DI
If you want to be able to easily test classes in isolation (https://en.wikipedia.org/wiki/Inversion_of_control)
probably others ...
If there are good arguments to use DI, but you also want new instances then you can just provide a factory.
This answer https://stackoverflow.com/a/36046754/217408 contains a concrete example how to do that.
Using DI is usually a good idea. There are IMHO no strong arguments against using DI. Only when none of the above arguments apply and providing factories is too cumbersome, use new Xxx() instead.

How to resolve a type by name from the container at runtime using Autofac?

I am trying to figure out how to resolve a type by name from the container at runtime using Autofac 3.5.2. My use case is that each business partner has a custom callback strategy that require injection of different types by the container, but I don't know which partner strategy I need until runtime. So:
class PartnerAStrategy(ISomeType aSomeType, ILog someLog) : ICallbackStrategy {}
and
class PartnerBStrategy(ISomeOtherType aSomethingElse, IShoe aSneaker) : ICallbackStrategy {}
I know which strategy I need after the class that will use it has already been resolved
class PartnerSSOController {
void PartnerSSOController(IPartnerFactory aFactory){
thePartnerFactory = aFactory;
}
void DoLogin(){
// 'PartnerB'
string aPartner = GetPartnerNameFromContext();
//get from container, not reflection
ICallbackStratgey aStrategy = thePartnerFactory.ResolveCallback(aPartner);
aStratgey.Execute();
}
}
class PartnerFactory : IPartnerFactory{
ICallbackStratgey ResolveCallback(string aPartnerName){
string aCallbackTypeINeed = string.format("SSO.Strategies.{0}Strategy", aPartnerName);
// need container to resolve here
}
}
Assuming that everything has been successfully registered with the container, how would I register the callback in my Autofac SSO module? I've tried this:
aBuilder.Register(aComponentContext => {
IPartnerFactory aFactory = aComponentContext.Resolve<IPartnerFactory>();
string aTypeName = String.Format("SSO.Strategies.{0}Strategy", /** how to access partner name here? **/);
Type aTypeToReturn = Type.GetType(aTypeName, false, true) ?? typeof(DefaultCallbackStrategy);
return aComponentContext.Resolve(aTypeToReturn);
})
.As<ICallbackStrategy>()
but as you can see, I can't figure out how to make the partner or type name available during callback.
I would prefer to avoid registering each partner's callback specifically and providing a key name, if possible, as I like to scan the assembly for the types in my module:
aBuilder.RegisterAssemblyTypes(typeof(CallbackBase).Assembly)
.Where(aType => typeof(ICallbackStrategy).IsAssignableFrom(aType))
.AsImplementedInterfaces()
.AsSelf();
I think what you're looking for is the Autofac metadata support, specifically the attribute metadata you can use with assembly scanning. Plenty of docs and examples here: http://autofac.readthedocs.org/en/latest/advanced/metadata.html
I think Travis' approach with using MetaData may have worked, but here is how I solved this problem today.
My real-world scenario uses an SSOPartner object rather than the string PartnerName that I used in my original question, so be aware of that.
First, I register all of the custom partner strategies in the SSO assembly by finding each type that implements ICallbackStrategy. CallbackBase is a type that is in the target assembly:
aBuilder.RegisterAssemblyTypes(typeof(CallbackBase).Assembly)
.Where(aType => typeof(ICallbackStrategy).IsAssignableFrom(aType))
.AsImplementedInterfaces()
.AsSelf();
Then I registered a Func<ISSOPartner, ICallbackStrategy> at the composition root:
aBuilder.Register<Func<ISSOPartner, ICallbackStrategy>>((aComponentContext, aPartner) => {
IComponentContext aResolvedContext = aComponentContext.Resolve<IComponentContext>();
return aSSOPartner => {
string aType = String.Format("SSO.Strategies.{0}Strategy", aSSOPartner.Name);
Type aCallbackType = Type.GetType(aType, false, true);
return (ICallbackStrategy)aResolvedContext.Resolve(aCallbackType, new NamedParameter("anSSOPartner", aSSOPartner));
};
});
As you can see, each strategy takes the SSOPartner object in the constructor as a named parameter. This helps demonstrate how an object can be resolved from the container using a mix of types, some of which are registered with the container and others which are not.
So let me update my original example:
class PartnerAStrategy(ISSOPartner anSSOPartner) : ICallbackStrategy {}
and
class PartnerBStrategy(ISSOPartner anSSOPartner, IShoe aSneaker) : ICallbackStrategy {}
aResolvedContext.Resolve will find PartnerB's IShoe at runtime by looking in the container. The container has no knowledge of ISSOPartner.
Finally, I take a dependency on the Func<ISSOPartner, ICallbackStrategy> in the location I need to use it and invoke it to call the lambda I defined at the composition root:
public class SSOController : Controller {
private readonly Func<ISSOPartner, ICallbackStrategy> theCallbackResolverFunc;
public SSOController(Func<ISSOPartner, ICallbackStrategy> aCallbackResolverFunc){
theCallbackResolverFunc=aCallbackResolverFunc;
}
public async Task<ActionResult> DoSSO() {
SSOPartner anSSOPartner = GetThePartner();
ICallbackStrategy aCallback = theCallbackResolverFunc.Invoke(anSSOPartner);
var aReturn = await aCallback.Execute();
...
}
}
The SSOController is passed a reference to the Func that I registered in the composition root. I execute that Func and pass in the SSOPartner which has a property called Name which I use to resolve the ICallbackStrategy type.

Difference between InputFilterAwareInterface and InputFilterProviderInterface in ZF2

Can someone explain me the difference between both interfaces InputFilterAwareInterface and InputFilterProviderInterface? Both seem to serve to the same purpose, to get an InputFilter, but I know they cannot be the same... And when do they get called?
Thanks
Both interfaces exist for different purposes. The InputFilterAwareInterface guarantees that implemented classes will have a setInputFilter() and getInputFilter() methods which accept and return an InputFilter instance when necessary. On the other hand, the InputFilterProviderInterface guarantees only that implemented classes will have a getInputFilterSpecification() method which returns a filter specification (configuration array) which is ready to use as argument in various input factories.
For example; the snippet below came from Zend\Form\Form.php class:
if ($fieldset === $this && $fieldset instanceof InputFilterProviderInterface) {
foreach ($fieldset->getInputFilterSpecification() as $name => $spec) {
$input = $inputFactory->createInput($spec);
$inputFilter->add($input, $name);
}
}
As you can see, the Form class creates inputs and binds them to related filter using given specification which is returned by getInputFilterSpecification() method of the implementing class ($fieldset int this case).
Using Traits
Zend Framework 2 also provides lot of traits for commonly used interfaces. For example InputFilterAwareTrait for InputFilterInterface. This means, you can easily implement that interface if you have PHP >= 5.4
namespace MyNamespace;
use Zend\InputFilter\InputFilterInterface;
MyClass implements InputFilterInterface {
// Here is the trait which provides set and getInputFilter methods
// with a protected $inputFilter attribute to all MyClass instances.
use \Zend\InputFilter\InputFilterAwareTrait;
// Your other methods.
...
}
Now anywhere in your code, you can do this:
$myClass->setInputFilter($AnInputFilterInstance);
$myClass->getInputFilter(); // Returns an inputfilter instance.
As you can imagine, no trait exists for InputFilterProviderInterface because its responsibility is only returning a valid config spec. It doesn't deal with any instance or class attribute like is forced in InputFilterInterface.

Is there a way to parametrize mixin in Groovy?

Can I somehow mixin a class with parameterized constructor?
Something like this:
class RenderedWithTemplates {
def templates = []
RenderedWithTemplates(templates) { ... }
...
}
#Mixin(RenderedWithTemplates(show: "showAddress.gsp", add: "addAddress.gsp")
class Address { ... }
I found the mixin proposal from 2007 [0], but the GroovyDefaultMethods#mixin [1] method has no support for parameterized mixins and neither has #Mixin.
As far as I can tell from the code example above, you need to find a way to mixin GSP view information that is tied to your (domain) classes. An alternative (and slightly groovier ;)) approach for this case would be to implement RenderedWithTemplates as annotation with a single closure parameter holding the GSP view information:
import java.lang.annotation.*
#Retention(RetentionPolicy.RUNTIME)
#interface RenderedWithTemplates {
Class value()
}
#RenderedWithTemplates({ [show: "showAddress.gsp", add: "addAddress.gsp"] })
class Address {}
// shows how to read the map with all the GSP infos
def templateInfo = Address.getAnnotation(RenderedWithTemplates)
def gspMap = templateInfo.value().newInstance(this, this).call()
[0] http://docs.codehaus.org/display/GroovyJSR/Mixins
[1] http://groovy.codehaus.org/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html

Resources