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

ventnor

v0.2.0

Published

A base class for browser views

Downloads

560

Readme

Ventnor

NPM

Build Status

This is a base class for views. Ventnor views provide:

  • a root DOM element
  • a means of observing models and other views
  • simple sub view management

If you have used Backbone before, Ventnor views may be familiar to you.

Ventnor views inherit their eventy behaviour from node event emitter.

Installation

npm install --save ventnor

API

Constructor

This is how you instantiate the base view. This isn't particularly useful though, normally you'd want to extend it. See the Extending Ventnor section.

var View = require('ventnor')

v = new View(Object: serviceLocator)

By convention, serviceLocator is a way of accessing application level services. This can be just a plain object, or an instance of serby/service-locator.

Properties

The constructor creates the following public properties on the view instance:

v.serviceLocator

Whatever was passed as the first argument to the constructor.

v.cid

A unique id.

v.el

A root DOM element (an HTMLDivElement)

v.$el

If jQuery is available this is the result of $(el)

Methods

v.listenTo(Object: obj, String: event, Function: fn)

Bind the callback fn to the event of the event emitter obj such that when the view is destroyed, the event listener is removed. obj should be an instance of the node event emitter.

v.listenToDom(Object: el, String: event, Function: fn)

Bind the callback fn to the event of the DOM element el such that when the view is destroyed, the event listener is removed.

v.stopListening()

Removes all event listeners bound with v.listenTo().

v.stopDomListening()

Removes all event listeners bound with v.listenToDom().

v.attachView(Object: view)

Attaches the given view such that when the view v is removed, any attached views are also removed. This function is for managing the lifecycle of nested views and preventing view leakage (views not being garbage collected even though they are never going to be in view again, which is a memory leak). A good rule of thumb is that if a view is responsible for instantiating another view, it should call attachView().

v.remove()

Removes the root element v.el from the document. This also removes all attached views and unbinds all event listeners.

v.getViewByModel(Object: model)

A lookup function for attached views. This will retrieve a view that has a model with the model.id or model.cid property equal to that of the given model.

v.getViewByModelId(String: id)

A lookup function for attached views. This will retrieve a view that has a model property with model.id or model.cid equal to that of the given id.

Events

v.on('remove')

View emits remove just before it is removed from the document and all of its listeners are removed.

Extending Ventnor for your own views

Ventnor doesn't do any fancy extend-y stuff, you just use built-in JS prototypal inheritence methods.

module.exports = ClockView

var View = require('ventnor')

function ClockView(serviceLocator) {
  // Call the view constructor
  View.apply(this, arguments)
}

// Set the object prototype
ClockView.prototype = Object.create(View.prototype)

// Now add custom methods to the new prototype

// By convention, view instances normally implement
// a render function which populates their DOM element
ClockView.prototype.render() = function () {
  this.el.textContent = new Date()).toString()
}
var ClockView = require('./clock-view')
  , v = new ClockView(serviceLocator)

Templating

Ventnor views are easy going as far as templates are concerned. Here's how to implement a view with Jade templates:

module.exports = ListItemView

var View = require('ventnor')
  , compileJade = require('browjadify-compile')

function ListItemView(serviceLocator, model) {
  View.apply(this, arguments)
  // Use a different root element type if you like
  this.el = document.createElement('li')
  // Store the model so it can be passed in to the template
  this.model = model
}

ListItemView.prototype = Object.create(View.prototype)

ListItemView.prototype.template = compileJade(__dirname + '/list-item.jade')

ListItemView.prototype.render = function () {
  this.el.innerHtml = this.template(this.model.toJSON())
  return this
}
.list-item-header #{name}
.list-item-content #{description}
var models = [ /* an array of Merstone models! */]
  , ListItemView = require('./list-item-view')

models.forEach(function (model) {
  listItem = new ListItemView(serviceLocator, model)
  document.getElementById('#item-list').appendChild(listItem.render().el)
})

// The document might now look something like this:
//
// <ul id="item-list">
//   <li>
//     <div class="list-item-header">Item #1</div>
//     <div class="list-item-content">The first item</div>
//   </li>
//   <li>
//     <div class="list-item-header">Item #2</div>
//     <div class="list-item-content">The second item</div>
//   </li>
// </ul>
//

The name?

I've made a bunch of MVC-like components. I named each one after villages on the Isle of Wight (where I live) beginning with the same letter as the thing it represents.

See also Merstone models and Chale collections.

Credits

Licence

Copyright (c) 2014, Ben Gourley

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.