Public Components¶
Wrappers¶
PorterJS exposes several convenience wrappers:
p.one()
p.all()
These methods are essentially just wrappers for document.querySelector
and document.querySelectorAll
. However, they can be chained together in any combination, unlike document.querySelector
and document.querySelectorAll
.
p.one('#some_id').all('p') >> OKAY
p.one('#some_id').one('p') >> OKAY
p.all('.some_class').one('p') >> OKAY
p.all('.some_class').all('p') >> OKAY
You can call addEventListener()
and removeEventListener
on an entire group of nodes, unlike in stock JavaScript. So, for example, the following would work as expected.
p.all('.some_class').addEventListener('click', callSomeFunction)
Also, another difference from document.querySelectorAll
and all
is that you can run a forEach
loop or a for-of
loop.
var q = p.all('.some_class');
q.forEach( function (item) {
...
})
for (var item of q) {
...
}
Methods¶
In addition, it also exposes some additional methods that are used under the hood, but can be helpful in creating UI components:
p.trigger_call()
p.ready()
p.debounce()
p.load()
Objects¶
There are several classes that are used under the hood. These too (like the methods above) may be useful.
p.events
¶
This is an instantiated instance of the Dispatcher
class. Essentially, it is the holding place for all custom events. It contains several methods that can be used to add, remove, and trigger custom events.
p.events.add(<NAME OF EVENT>,<CALLBACK>)
:- Used to record
<NAME OF EVENT>
as a potential event.
p.events.remove(<NAME OF EVENT>,<CALLBACK>)
:- Used to remove
<NAME OF EVENT>
as a potential event.
p.events.trigger(<NAME OF EVENT>,<ARGS>)
:- Used to trigger
<NAME OF EVENT>
.
var someFunction = function(arg1, arg2, arg3) {
...
}
p.events.add('myCustomEvent', someFunction)
p.events.trigger('myCustomEvent', arg1, arg2, arg3)
p.events.remove('myCustomEvent', someFunction)
p.stack
¶
This is an instantiated instance of the DataStack class. It is used to hold state for the application. Data is kept inside the p.stack.storage variable. HOWEVER, it is strongly encouraged to NOT directly access the p.stack.storage object. Doing so will cause a lot of unexpected results.
Instead, you shoule interact with the stack by using the getter and setter methods.
p.stack.set(<NAME OF KEY>, <VALUE>, <OPTIONAL CALLBACK>)
:- Used to store a key/value pair to state. If the optional callback is passed, it will be called after the key/value has been stored.
p.stack.get(<NAME OF KEY>, <OPTIONAL DEFAULT VALUE>)
:- Used to retrive a key/value pair from state. If the second, optional parameter is passed, it will return this as a default value if the
key
is not in thestate
.
p.stack.push(<NAME OF KEY>, <VALUE>, <OPTIONAL CALLBACK>)
:- Used to push a value to a an array in the state. If the optional callback is passed, it will be called after the value has been stored.
p.stack.update(<NAME OF KEY>, <NAME OF PROPERTY>, <VALUE>, <OPTIONAL CALLBACK>)
:- Used to change a single property of an object already stored in the stack. If the optional callback is passed, it will be called after the value has been stored.
Regardless of the key
, there will be an event emmitted when storing a key/value to the state
. Its name will be key + 'StackChange'
. Therefore, you can capture this by adding a custom event.
p.events.add('someKeyStackChange', function() {
console.log('This event was triggered by pushing an item to the stack')
console.log('The value of someKey is: ' + p.stack.get('someKey'))
})
p.stack.set('someKey', 'abcdefg')
This also works with the push()
method.
p.events.add('someKeyStackChange', function() {
var my_list = p.stack.get('someKey')
console.log('This event was triggered by pushing an item to the stack')
console.log('There are ' + my_list.length + ' items in somKey')
})
p.stack.push('someKey', 'abcdefg')
You can get all of the keys that have been set with the .keys()
method.
for (var key of p.stack.keys()) {
console.log(key)
}
Sometimes you do not want to override an entire object that is stored in the stack
. What if you only want to update a single property? No problem, call .update()
.
var nested = {
inner: {
property: {
found: {
here: 'Hello, world.'
}
}
}
}
p.stack.set('nested', nested)
p.stack.update('nested', 'inner.property.found.here', 123)
p.Request
¶
This is an object used to make AJAX calls, and to return a response. To begin, it should be instantiated with a URL as its parameter.
var request = p.Request("http://example.com")
To actually make a call, you call either post()
or get()
on it. Both methods take data
as its first argument.
The data
variable can either be a url encoded string (foo=bar
) or an object ({'foo': 'bar'}
).
In addition, the post()
method also takes an additional second parameter: csrftoken
. This is a string that gets passed through to a X-CSRFToken
header. Right now, I know this is limited functionality that is screaming of some need for further abstraction. But, PorterJS was developed first and foremost to run with a Django backend, hence the csrftoken
in this form. Future releases will abstract away this logic, and also add better logic for adding headers.
To see this in action:
request.get().then(function (response) {
console.log(response.responseText)
}).catch(function (error) {
console.log(error)
})