I have a question about declaring $helper explicitly.
This is sample code from CakePHP Book.
<?php
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
..
}
In my code, I didn't have that declaration at all, but my app is still working, I can save data via my web form, I can also using $this->Html->link().
Do I really need that declaration, any disadvantages if I didn't?
Thanks to all.
The $helpers variable only needs to be declared when you are using a Helper other than 'HTML' and 'Form'. The core helpers 'Html' and 'Form' are loaded by default into the $helpers array, so the declaration is unnecessary if you only intend to use these.
If you want to add a custom helper, or use any other core helper, then you must declare the $helpers array. When you do this, you are overwriting the default helpers array, so you need to make sure to include the defaults again if you still intend to use them.
// Default. You do not need to declare this if you
// only intend to use these helpers.
$helpers = array('HTML', 'Form');
// Add 'CustomHelper' to $helpers array. In this case
// HTML and Form must be declared.
$helpers = array('HTML', 'Form', 'Custom');
Related
With react, in the JSX code returned by a functional component I can have:
MyComponent.jsx
<MySubComponent props1={{a: 0, b:1}}/>
OR
<MySubComponent props2={["toto", "tata"]}/>
Where my sub component is exported with memoization:
MySubComponent.jsx
export default React.memo(MySubComponent)
However this breaks memoization, because props with the format {{...}} or {[...]} will instanciate a new object/array each time (same value, but different memory address), thus props shallow-compare by React.memo sees it different.
Is there any ESLint/JSLint rule to detect those kinds of props ?
You can use useMemo to memoize the object or array and pass it as props to MySubComponent like this:
const obj = React.useMemo(() => ({a: 0, b:1}), []);
<MySubComponent props1={obj}/>
In SubComponent.jsx
export default React.memo(MySubComponent);
This only works for simple objects.
In a parent component I have something like:
render() => {
const data = {a:1,b:[1,2,3]}; // of course this is a simplified version of the code
return html`<child-component data=${data}></child-component>`
}
Which is basically equivalent to:
render() => {
const data = {a:1,b:[1,2,3]}; // of course this is a simplified version of the code
return html`<child-component data="[object Object]"></child-component>`
}
Which is basically useless...
Is there a simple way to pass complex object hierarchies into litElement components?
As far as I can tell, my options are:
Option 1. Use attributes: I'm a bit of a litElement noob so I'm not sure if this will work and I'm not sure how to make it work without having to make extra function calls. It would be nice if I could just do all the necessary work inside html.
Research in progress.
Option 2. Use Json.
Stringify the object in the parent component
render() => {
const data = {a:1,b:[1,2,3]}; // of course this is a simplified version of the code
return html`<child-component data=${JSON.stringify(data)}></child-component>`
}
then parse the json in the child component.
This just seems a bit inelegant to me though.
But it works.
In this case what you probably want is to pass the object as a property rather than as an attribute. For complex data such as objects, arrays, functions, etc. that's the preferred method.
You can do it with the following syntax:
render() => {
const data = {a:1,b:[1,2,3]};
// note the period (.), that's the token used to identify that you're passing data as a property
return html`<child-component .data=${data}></child-component>`
}
In general, you should probably give Lit's templating guide a read as some of the most common use cases are covered throughout it.
Where should I put following line to get my component ready?
const classes = useStyles();
Try to use Material-UI MenuList component, but need to use in my existing MainPage code, what is slightly different from Material-UI code example.
constants are not supported at class level.
You have two options.
move the constants out of class and refer then.
Use static properties
This thread has some more information.
Declaring static constants in ES6 classes?
Could you try to call it inside render lifecycle ?
If i'm not wrong, u can't create const directly inside class, the order should be class > function > const or let var
Or you can try to put it inside constructor
Constructor(props) {
super(props)
this.classes = useStyles()
}
Or you can do it like seanplwong suggest
I think for class properties, the syntax should be something like
class Foo {
classes = useStyle();
}
I'm writing a wrapper around a js library with Polymer components. Basically, I need to be able to assign attributes to a component, and forward them to an instance of a js object.
The problem is that Polymer (or webcomponents in general?) forces attribute names to be lowercase.
Declaring the element
<some-element fooBar="baz"></some-element>
Generic change listener
attributeChanged: function(attrName, oldVal, newVal){
// attrName -> foobar, which is not a member of someInstance
this.someInstance[attrName] = newVal;
}
Is there some way to get the camel-cased name? Maybe I can create a hash from the publish object on the prototype... but how do I reference that?
Aha! publish is actually available on the component instance! This allows me to grab the names and make a map from lowercase to camelcase.
var map = {};
Object.keys(this.publish).forEach(function(key){
map[key.toLowerCase()] = key;
});
I would like to include standard functionality in several views within an Ember app. The functionality includes things like setting the tagName and classNames of the views to be the same and keeping track of a property for each view.
The question in a nutshell: Should I use a mixin or extend a base view?
The expanded question...
Should one extend a base view to do this? For example:
App.BaseView = Em.View.extend({
tagName: 'section',
classNames: ['page_section', 'blue'],
willInsertElement: function() {
// Some functions called here that set properties
},
});
App.PageOneView = App.BaseView.extend({
// View specific stuff here
});
App.PageTwoView = App.BaseView.extend({
// View specific stuff here
});
... Or, should one use a Mixin to extend the functionality? For example:
App.BaseMixin = Em.Mixin.create({
tagName: 'section',
classNames: ['page_section', 'blue'],
willInsertElement: function() {
// Some functions called here that set properties
},
});
App.PageOneView = Em.View.extend(App.BaseMixin, {
// View specific stuff here
});
App.PageTwoView = Em.View.extend(App.BaseMixin, {
// View specific stuff here
});
I understand that views and mixins are both Ember objects, but does using either of them to extend standard functionality to other objects (e.g. views) affects how the objects and prototypes/instances (if they differ from the object) interact and whether properties get set on the instance of the view or the view object?
If the two examples above differ, would setting the properties on the mixin's init function change anything? For example:
App.BaseMixin = Em.Mixin.create({
tagName: null,
classNames: null,
init: function() {
this.set('tagName', 'section');
// And so forth...
},
});
However, if using a mixin and extending a view have the same affect on the views I am trying to add the standard functionality to (that is, they affect the views' objects and prototypes/instances in the same way), do you see an advantage to using one over the other (whether in terms of efficiency, maintainability, etc)?
Great question,
Short and simple, extend the view.
The hooks/bindings are view specific, so the mixin can't be applied to a controller, route etc, and depending on your team makeup, you don't want to give someone an opportunity to mix in code that doesn't belong.
Extending a class in Ember just makes the base class into a mixin and applies it to your class. https://github.com/emberjs/ember.js/blob/v1.2.0/packages/ember-runtime/lib/system/core_object.js#L488
So it's almost the exact same thing, only your base view makes more sense since it only really applies to views.