npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@webhandle/backbone-view

v1.0.2

Published

A replacement for Backbone's View.

Downloads

25

Readme

Webhandle Backbone View

A replacement for Backbone's View.

I really like Backbone's View. It's a perfect level of abstraction and container for when a framework is too big and managing a few different object types becomes messy.

However, it requires jQuery and Underscore, which add a staggering 600k to the bundle making it unsuitable for the creation of little modules. Additionally, its code was written to run on older IE browsers and still uses that packaging and those techniques.

While that level of backward compatibility can be useful, I want to write code that uses classes, modules, etc, and want my tools to support that.

Install

npm install @webhandle/backbone-view

It's about 1027 bytes zipped as part of a webpack bundle, so about 1% of the size of Backbone and its dependencies.

Usage

Import like

const View = require('@webhandle/backbone-view').View

or

import { View } from '@webhandle/backbone-view'

Backbone's actual documentation is still pretty descriptive of what this does. But in brief, the basic process is to extend View and define how the data will be rendered and how events will be handled.

Setting callbacks to handle events is done by creating an events object, where this.events is a hash like:

{"event selector": "callback"}

Events are things like click and mousedown. Selectors are standard css selectors like button, footer .ok, or .ok. Each selector is assumed to target only elements within the view. A special selector value, ., is used to indicate the root element of the view.

Events are handled by event listeners on the view's root element. That means that while you have to have the events defined when the view is created, you can change the content of the view's dom section however you want and whenever you want. Events on those new elements will still get handled.

Callbacks are either a string, which refers to a method of the view, or functions. In either case the method/function will be called with the view as the this object. These functions will receive the dom event and the element matching the selector which the event bubbled through. This may not be the same as the evt.target since a child element of the matching element may have been the actual thing clicked (or whatever). Essentially, the second argument is what the evt.target would have been if the event listener had been added directly to that element instead of the view root.

Rendering (via the render method) is the most free from. It requires that the contents of this.el (the view's root element) get modified to show content appropriate to this.model. You can use any templating library or no templating library at all.

Include the view into the page by adding the view object's el (the root element of the view) to any place in the dom. There are two convience functions appendTo and replaceContentsOf.

And don't forget to call render, either before or after the element is added to the dom, or you won't see any content.

import { View } from '@webhandle/backbone-view'

class DollarView extends View {
	preinitialize() {
		this.events = {
			'click .one': 'oneClicked',
			'click .': function (evt) {
				console.log(`${this.model} it got clicked`)
			}
		}
	}

	render() {
		this.el.innerHTML = "$" + `<span id="${this.id}one" class="one"><span id="${this.id}two" class="two">${parseFloat(this.model)}</span></span>`
		return this
	}

	oneClicked(evt, selected) {
		console.log(`one clicked ${selected.id}`)
	}
}

let one = new DollarView({
	model: 123.45
})

one.render()
one.appendTo(document.body)

A view will accept the options 'model', 'el', 'id', 'attributes', 'className', 'tagName', and 'events'. It's possible to pass these in as options to an instance or as options via the subclass's constructor. However, I think it looks cleaner to implement the preinitialize function, which is called before the view creates any elements.

Differences from Backbone

As mentioned above, there are no dependencies. The View also lacks some of the functions used by Backbone for interaction with its Model and Collections components. Since there is no jQuery, some of the members like this.$el don't exist and events will be plain HTML dom events.

Backbone also limits which members of the options will be added to the View instance object to those listed above. That seems unnecessarily limiting so this View adds all members.

While broadly compatible, I wouldn't expect the behaviors to be identical.

An Only Slightly More Complicated Example

import { View } from '@webhandle/backbone-view'

class DollarView extends View {
	preinitialize() {
		this.events = {
			'click .one': 'oneClicked'
			, 'click .math-button': 'doMath'
			, 'click .': function (evt) {
				console.log(`${this.model} it got clicked`)
			}
		}
	}

	render() {
		this.el.innerHTML = "$" + `<span id="${this.id}one" class="one"><span id="${this.id}two" class="two">${parseFloat(this.model)}</span></span><button class="add-one math-button">Add One</button><button class="substract-one math-button">Subtract One</button>`
		return this
	}

	oneClicked(evt, selected) {
		console.log(`one clicked ${selected.id}`)
	}

	doMath(evt, selected) {
		if(selected.classList.contains('add-one')) {
			this.model = this.model + 1
		}
		else if(selected.classList.contains('subtract-one')) {
			this.model = this.model - 1
		}
		this.el.querySelector('.two').innerHTML = parseFloat(this.model)
		console.log(this.randomInfo)
	}
}

let one = new DollarView({
	model: 1.45
	, randomInfo: 20
})

one.render()
one.appendTo(document.body)