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

model-citizen

v0.5.1

Published

Very simple client-side models with events and computed properties

Downloads

7

Readme

citizen

Minimal data models with change events and computed properties for your js views.

Data models provided by citizen are just data models. They don't come with syncing or validation; other libraries can provide that.

ie6+

installation

with component

component install the-swerve/citizen

api

Model.clone(data)

Instantiate by creating a Model object, optionally passing in any initial data.

var Model = require('citizen')
var post = Model.clone()

Model.set(data)

Pass an object of properties mapped to values to set new data.

post.set({title: "lol javascript"})

Model.get('property')

Retrieve any property, including computed properties.

post.get('title') // 'sup friends'

Model.where(name, dependents, fn)

Create a computed property by using where, setting the property name, and using a function whose parameters are other properties that it depends on.

post.where('capitalized_title', ['title'], function(title) {
	var words = title.split(' ')
	var caps = words.map(function(w) {
		return w[0].toUpperCase() + w.substr(1).toLowerCase()
	})
	return caps.join(' ')
})

post.get('title') // 'sup friends'
post.get('capitalized_title') // 'Sup Friends'

The above will set a 'capitalized_title' property based on a post's title property. We have to list each dependent property explicitly as a string since so many minifiers/uglifiers will change local variable names, so we can't necessarily extract the property names from the parameters in the supplied function.

Properties are lazy. They will be computed when they are accessed. You also don't need to set the dependent properties before depending on them.

Model.has_one(property_name, Model)

has_one creates a nested Model. It lets you have a field in your model that's automatically instanstiated as another model.

var comment = Model()
post.has_one('comment', Comment)
post.set({comment: {text: 'my comment'}, plain_obj: {plain_prop: 'hallo welt'}})

post.get('comment').get('text') // 'my comment'
post.get('plain_obj').plain_prop // 'hallo welt'

That way, every time you set a comment object inside post, it will be a Model rather than just a plain Object.

Model.has_many(property, Model)

If you want your model to have an array of other models nested inside of it, use has_many

Create a post with a nested collection of comments under the property 'comments'

var comment = Model()

// Take any comment and append #syngery
Comment.where('better_comment', function(text) {
	return text + ' #synergy'
})

var post = Model()
post.has_many('comments', Comment)
var post = new Post({comments: [{text: 'wut', text: 'wat'}]})

var comments = post.get('comments')
comments[0].better_comment // 'wut #synergy'

Now, Post has a property called 'comments' that holds an array of comment Models, with each Comment having its own set of computed properties and change events that are settable and gettable through a post. This nested array of models will only get instantiated when the whole thing is set, and not on push or assigning to individual indexes (for now).

events

citizen emits 'change' and 'change {property}' events when a property has been set.

var changed = false
post.on('change title', function() { changed = true })
post.set('title', 'js party')
// changed === true

citizen also emits 'change {computed_property}' events for computed properties. If any properties that a computed property depends on are changed, a change event for that computed property is emitted.

var changed = false
post.on('change capitalized_title', function() { changed = true})
post.set('title', 'such compute wow amaze')
// changed === true

You can get 'change {has_one}' and 'change {has_many}' events as expected, and for changes on models within collections, those individual models will emit their own change events.