Currently I have two Polymer components that share a great amount of data. You can see here:
<polymer-component1
series="{{series}}"
stackhelper={{stackhelper}}
stack={{stack}}
controls={{controls}}
camera={{camera}}
threed={{threed}}
scene={{scene}}
renderer={{renderer}}>
</polymer-component1>
<polymer-component2
stackhelper=[[stackhelper]]
stack={{stack}}
controls={{controls}}
camera={{camera}}
threed={{threed}}
scene={{scene}}
renderer={{renderer}}
guiobjects={{guiobjects}}>
</polymer-component2>
This is working fine right now but whats the best practice about sharing data? Any way to share all the properties between two components?
It's recommended to share data through data binding, just as what you're doing. You can share any property, not just strings and numbers. e.g. assuming you have an object
JS
data = {
series: "",
stackhelper: "",
stack: "",
controls: "",
camera: "",
threed: "",
scene: "",
renderer: "",
}
Your code can be rewritten like this.
HTML
<polymer-component1 data="{{data}}"></polymer-component1>
<polymer-component2 data="{{data}}"></polymer-component2>
In Polymer 2 one element can just inherit the properties by extending it.
class MyElementSubclass extends MyElement {...}
Or you create an element with just the properties both need and then both components extend the parent. You can find this here scroll down to Extending an existing element
Related
I want to add badge in nebular menu for inbox count dynamically. Help me on this. Thanks
import { NbMenuItem } from '#nebular/theme';
export const MENU_ITEMS: NbMenuItem[] = [
{
title: 'Dashboard',
link: '/pages/dashboard',
home: true,
},{
title: 'Inbox',
link: '/pages/inbox',
home: true,
}]
I would like to extend the question and ask if it is possible to place a custom component or at least HTML tags within the menu item? Currently the interface allow only string (title) ...
The question above (about adding a badge) is just an example for the missing functionality - enable formatting of the menu item.
I would appreciate an example code to solve this limitation, even if it contains extending nebular framework classes.
Thx,
Yohay
Is it possible to insert custom widget (for example button or checkbox) in gridpanel column header?
From documentation it's unclear.
Already I've tried to google it, but without any success.
Please help!
The short answer is 'yes'.
You can extend the grid column, then make an afterrender listener.
In the listener, get the column's innerEl = (component.getEl().down('column-header-inner').
Then, make a new component like button/checkbox, columnComponent.headerButton = new Ext.button.Button()
Then, render it columnComponent.headerButton.render(innerEl).
I hope this helps.
I had the same problem: How to get a button (or any custom component) into the extjs grid header field.
After some research I found the solution for extjs 5: You can configure the "items" property of the grid columns:
{
xtype: "gridcolumn",
text: "column header name in grid",
dataIndex: "...",
items:[
{
xtype: "button",
text: "Foo",
handler: "onFooClick"
}
]
}
This will for example show a button under the grid header text inside the header component.
I've been reading up on web components and am pretty intrigued by the nascent spec. Does anyone know if there is any support for 2-way data binding in the DOM, without having to use Polymer? An example would be appreciated.
Object.observe is a potential new way to do databinding in javascript. This feature is scheduled for Ecmascript 7(javascript), but some browsers currently support it, check here. Also check out this html5rocks article on object.observe
No, data binding isn't part of the Web Components spec.
You can of course implement data binding yourself using native JavaScript event listeners, and possibly the Proxy object, but it's probably best not to re-invent the wheel: if you want data binding, choose one of the many JavaScript frameworks out there which supports that. Polymer, React, Angular, and Vue are some recent examples of such libraries.
I've been playing around with this over the last few days. You can create a StateObserver class, and extend your web components from that. A minimal implementation looks something like this:
// create a base class to handle state
class StateObserver extends HTMLElement {
constructor () {
super()
StateObserver.instances.push(this)
}
stateUpdate (update) {
StateObserver.lastState = StateObserver.state
StateObserver.state = update
StateObserver.instances.forEach((i) => {
if (!i.onStateUpdate) return
i.onStateUpdate(update, StateObserver.lastState)
})
}
}
StateObserver.instances = []
StateObserver.state = {}
StateObserver.lastState = {}
// create a web component which will react to state changes
class CustomReactive extends StateObserver {
onStateUpdate (state, lastState) {
if (state.someProp === lastState.someProp) return
this.innerHTML = `input is: ${state.someProp}`
}
}
customElements.define('custom-reactive', CustomReactive)
class CustomObserved extends StateObserver {
connectedCallback () {
this.querySelector('input').addEventListener('input', (e) => {
this.stateUpdate({ someProp: e.target.value })
})
}
}
customElements.define('custom-observed', CustomObserved)
<custom-observed>
<input>
</custom-observed>
<br />
<custom-reactive></custom-reactive>
fiddle here
I like this approach because it occurs directly between precisely those elements you want to communicate with, no dom traversal to find data- properties or whatever.
One way: $0.model = {data}; setter on $0 assigns $0.data, responding to the update, and the other way: $1.dispatchEvent(new CustomEvent('example', {detail: $1.data, cancelable: true, composed: true, bubbles: true})); with $0.addEventListenever('example', handler) gives 2 way data binding. The data object is the same, shared on 2 elements, events and setters allow responding to updates. To intercept updates to an object a Proxy works model = new Proxy(data, {set: function(data, key, value){ data[key] = value; ...respond... return true; }}) or other techniques. This addresses simple scenarios. You might also consider looking at and reading the source for Redux, it provides conventions that seem relatively popular. As Ajedi32 mentions reinventing the wheel for more complex scenarios is not so practical, unless it's an academic interest.
Code:
items: [{
xtype: 'segmentedbutton',
disabled: true,
//id:'segmentWidget',
items: [
{
text: 'text1',
flex: 1,
},
{
text: 'text2',
flex: 1
},
{
text: 'text2',
flex: 1
}
]
}]
Ext.getCmp('segmentWidget').setPressedButtons(0);
How can i do this without using ID
Thanks
If you don't want to use id to select components in Sencha (and it is a good idea to do that when possible to keep things reusable and avoiding polluting the global ids space) you have several options.
(bold part is taken from Sencha docs, the rest is mine)
Ext.Container.getComponent() method: Examines this container's items property and gets a direct child component of this container. Basically you pass in a string which should match the id or itemIdproperty of one of the items in that container.
Ext.Container.query() method: Retrieves all descendant components which match the passed selector. Executes an Ext.ComponentQuery.query using this container as its root. This returns an array of Ext.Component. Take a look at Ext.ComponentQuery.querydocs to understand which queries you can do. In short, you can simply select by xtype, in your case you can do: fatherComponent.query('segmentedbutton')[0], or by another property, for example: fatherComponent.query('[text=text1]')[0]
Ext.Component.up() method: Walks up the ownerCt axis looking for an ancestor Container which matches the passed simple selector.
I am having a horrible time understanding Sencha Touch 2's architecture. I'm finding even the most basic things I do in other language and frameworks to be incredibly painful.
Currently, I just want to do a standard Master/Detail view. I load a store into a list view and would like to click on each list item to slide in a detail view. Since my initial list view can contain quite a lot of items, I'm only loading a little bit of the data with this method in my controller:
viewUserCommand: function(list, record) {
// console.log(record);
var profileStore = Ext.getStore("Profiles");
profileStore.setProxy({
url: 'http://localhost:8000/profile/' + record.data.user_id
});
profileStore.load();
// console.log(profileStore);
Ext.Viewport.animateActiveItem(Ext.getCmp('profileview'), this.slideLeftTransition);
}
First, modifying the url property for each tap event seems a bit hacky. Isn't there a way to specify "this.id" or something along those lines, and then pass that to my store? Or would that require loading the entire DB table into an object?
I can console.log the return from this method and it's exactly what I want. How do I populate the detail view? I've tried utilizing a DataView component, but it doesn't show any data. The examples on sencha's website are fairly sparse, and relatively contextless. That means that even copying and pasting their examples are likely to fail. (Any examples I've tried using Ext.modelMgr.getModel() have failed.)
I know it's partly that this framework is new and I'm probably missing a huge gaping hole in my understanding of it, but does anyone have any clue?
Would suggest you check out the docs, there's an example of loading a single model:
http://docs.sencha.com/touch/2-0/#!/api/Ext.data.Model
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: ['id', 'name', 'email'],
proxy: {
type: 'rest',
url : '/users'
}
}
});
//get a reference to the User model class
var User = Ext.ModelManager.getModel('User');
//Uses the configured RestProxy to make a GET request to /users/123
User.load(123, {
success: function(user) {
console.log(user.getId()); //logs 123
}
});